From dc45ec62c2f5dfcc895854dfbddf6fe9621d3072 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Mon, 14 Jan 2019 20:04:45 +0300 Subject: [#477] User search improvements: tsquery search with field weights, friends & followers boosting. --- lib/pleroma/user.ex | 75 +++++++++++++++++++--- .../web/mastodon_api/mastodon_api_controller.ex | 6 +- .../web/twitter_api/twitter_api_controller.ex | 2 +- 3 files changed, 70 insertions(+), 13 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 681280539..52638b446 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -35,7 +35,7 @@ defmodule Pleroma.User do field(:avatar, :map) field(:local, :boolean, default: true) field(:follower_address, :string) - field(:search_distance, :float, virtual: true) + field(:search_rank, :float, virtual: true) field(:tags, {:array, :string}, default: []) field(:last_refreshed_at, :naive_datetime) has_many(:notifications, Notification) @@ -511,6 +511,12 @@ defmodule Pleroma.User do {:ok, Repo.all(q)} end + def get_followers_ids(user, page \\ nil) do + q = get_followers_query(user, page) + + Repo.all(from(u in q, select: u.id)) + end + def get_friends_query(%User{id: id, following: following}, nil) do from( u in User, @@ -535,6 +541,12 @@ defmodule Pleroma.User do {:ok, Repo.all(q)} end + def get_friends_ids(user, page \\ nil) do + q = get_friends_query(user, page) + + Repo.all(from(u in q, select: u.id)) + end + def get_follow_requests_query(%User{} = user) do from( a in Activity, @@ -666,7 +678,7 @@ defmodule Pleroma.User do Repo.all(query) end - def search(query, resolve \\ false) do + def search(query, resolve \\ false, for_user \\ nil) do # strip the beginning @ off if there is a query query = String.trim_leading(query, "@") @@ -674,16 +686,28 @@ defmodule Pleroma.User do User.get_or_fetch_by_nickname(query) end + processed_query = + query + |> String.replace(~r/\W+/, " ") + |> String.trim() + |> String.split() + |> Enum.map(&(&1 <> ":*")) + |> Enum.join(" | ") + inner = from( u in User, select_merge: %{ - search_distance: + search_rank: fragment( - "? <-> (? || coalesce(?, ''))", - ^query, - u.nickname, - u.name + """ + ts_rank_cd( + setweight(to_tsvector('simple', regexp_replace(nickname, '\\W', ' ', 'g')), 'A') || + setweight(to_tsvector('simple', regexp_replace(coalesce(name, ''), '\\W', ' ', 'g')), 'B'), + to_tsquery('simple', ?) + ) + """, + ^processed_query ) }, where: not is_nil(u.nickname) @@ -692,11 +716,44 @@ defmodule Pleroma.User do q = from( s in subquery(inner), - order_by: s.search_distance, + order_by: [desc: s.search_rank], limit: 20 ) - Repo.all(q) + results = + q + |> Repo.all() + |> Enum.filter(&(&1.search_rank > 0)) + + weighted_results = + if for_user do + friends_ids = get_friends_ids(for_user) + followers_ids = get_followers_ids(for_user) + + Enum.map( + results, + fn u -> + search_rank_coef = + cond do + u.id in friends_ids -> + 1.2 + + u.id in followers_ids -> + 1.1 + + true -> + 1 + end + + Map.put(u, :search_rank, u.search_rank * search_rank_coef) + end + ) + |> Enum.sort_by(&(-&1.search_rank)) + else + results + end + + weighted_results end def blocks_import(%User{} = blocker, blocked_identifiers) when is_list(blocked_identifiers) do diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index a8fe9d708..54367f586 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -772,7 +772,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do - accounts = User.search(query, params["resolve"] == "true") + accounts = User.search(query, params["resolve"] == "true", user) statuses = status_search(user, query) @@ -796,7 +796,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do - accounts = User.search(query, params["resolve"] == "true") + accounts = User.search(query, params["resolve"] == "true", user) statuses = status_search(user, query) @@ -817,7 +817,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def account_search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do - accounts = User.search(query, params["resolve"] == "true") + accounts = User.search(query, params["resolve"] == "true", user) res = AccountView.render("accounts.json", users: accounts, for: user, as: :user) diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 1c728166c..ede079963 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -675,7 +675,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end def search_user(%{assigns: %{user: user}} = conn, %{"query" => query}) do - users = User.search(query, true) + users = User.search(query, true, user) conn |> put_view(UserView) -- cgit v1.2.3 From 5b8f9ff8c14b5992e3db7a0c890ca5539e6a0086 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Tue, 15 Jan 2019 13:05:25 +0300 Subject: [#477] User search tests. Normalized search rank in User.search. --- lib/pleroma/user.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 52638b446..2488697bb 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -704,7 +704,8 @@ defmodule Pleroma.User do ts_rank_cd( setweight(to_tsvector('simple', regexp_replace(nickname, '\\W', ' ', 'g')), 'A') || setweight(to_tsvector('simple', regexp_replace(coalesce(name, ''), '\\W', ' ', 'g')), 'B'), - to_tsquery('simple', ?) + to_tsquery('simple', ?), + 32 ) """, ^processed_query -- cgit v1.2.3 From 0bc6d30f7dfe53be588329e48f1255b5eef18a2a Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Wed, 16 Jan 2019 10:44:32 +0300 Subject: [#477] Minor refactoring (user search query). --- lib/pleroma/user.ex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 2488697bb..8ae36416a 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -702,12 +702,14 @@ defmodule Pleroma.User do fragment( """ ts_rank_cd( - setweight(to_tsvector('simple', regexp_replace(nickname, '\\W', ' ', 'g')), 'A') || - setweight(to_tsvector('simple', regexp_replace(coalesce(name, ''), '\\W', ' ', 'g')), 'B'), + setweight(to_tsvector('simple', regexp_replace(?, '\\W', ' ', 'g')), 'A') || + setweight(to_tsvector('simple', regexp_replace(coalesce(?, ''), '\\W', ' ', 'g')), 'B'), to_tsquery('simple', ?), 32 ) """, + u.nickname, + u.name, ^processed_query ) }, -- cgit v1.2.3 From 2bfae25a1ff735499e15cb431314503f34097a6b Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Thu, 17 Jan 2019 18:03:49 +0300 Subject: [#491] Made user bio preserve full nicknames (nick@host). --- lib/pleroma/formatter.ex | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index 4149265a2..024c6e117 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -142,12 +142,11 @@ defmodule Pleroma.Formatter do ap_id end - short_match = String.split(match, "@") |> tl() |> hd() + full_match = String.trim_leading(match, "@") {uuid, - "@#{ - short_match - }"} + "" <> + "@#{full_match}"} end) {subs, uuid_text} -- cgit v1.2.3 From 2479e88815480a6417a16541c5e6da149e2e7ff9 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 17 Jan 2019 23:12:42 +0000 Subject: activitypub: announce: add new public parameter --- lib/pleroma/web/activity_pub/activity_pub.ex | 5 +++-- lib/pleroma/web/activity_pub/utils.ex | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 5b87f7462..8c852edbd 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -224,10 +224,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do %User{ap_id: _} = user, %Object{data: %{"id" => _}} = object, activity_id \\ nil, - local \\ true + local \\ true, + public \\ true ) do with true <- is_public?(object), - announce_data <- make_announce_data(user, object, activity_id), + announce_data <- make_announce_data(user, object, activity_id, public), {:ok, activity} <- insert(announce_data, local), {:ok, object} <- add_announce_to_object(activity, object), :ok <- maybe_federate(activity) do diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 6ecab773c..d2e457a68 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -386,9 +386,10 @@ defmodule Pleroma.Web.ActivityPub.Utils do """ # for relayed messages, we only want to send to subscribers def make_announce_data( - %User{ap_id: ap_id, nickname: nil} = user, + %User{ap_id: ap_id} = user, %Object{data: %{"id" => id}} = object, - activity_id + activity_id, + false ) do data = %{ "type" => "Announce", @@ -405,7 +406,8 @@ defmodule Pleroma.Web.ActivityPub.Utils do def make_announce_data( %User{ap_id: ap_id} = user, %Object{data: %{"id" => id}} = object, - activity_id + activity_id, + true ) do data = %{ "type" => "Announce", -- cgit v1.2.3 From 8e9f1d55876a282aa9f6f5358dc2db8715c13bff Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 17 Jan 2019 23:13:54 +0000 Subject: activitypub: relay: chase selective public announce changes --- lib/pleroma/web/activity_pub/relay.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/relay.ex b/lib/pleroma/web/activity_pub/relay.ex index abddbc790..c0a52e349 100644 --- a/lib/pleroma/web/activity_pub/relay.ex +++ b/lib/pleroma/web/activity_pub/relay.ex @@ -40,7 +40,7 @@ defmodule Pleroma.Web.ActivityPub.Relay do def publish(%Activity{data: %{"type" => "Create"}} = activity) do with %User{} = user <- get_actor(), %Object{} = object <- Object.normalize(activity.data["object"]["id"]) do - ActivityPub.announce(user, object) + ActivityPub.announce(user, object, nil, true, false) else e -> Logger.error("error: #{inspect(e)}") end -- cgit v1.2.3 From 33b473cc021d2d027c11021178af90298230e06e Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 17 Jan 2019 23:17:59 +0000 Subject: activitypub: allow is_public?() to work on any type of map representing an AS2 object --- lib/pleroma/web/activity_pub/activity_pub.ex | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 8c852edbd..92c5ce2ae 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -797,13 +797,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end end - def is_public?(%Object{data: %{"type" => "Tombstone"}}) do - false - end + def is_public?(%Object{data: %{"type" => "Tombstone"}}), do: false + def is_public?(%Activity{data: data}), do: is_public?(data) - def is_public?(activity) do - "https://www.w3.org/ns/activitystreams#Public" in (activity.data["to"] ++ - (activity.data["cc"] || [])) + def is_public?(data) do + "https://www.w3.org/ns/activitystreams#Public" in (data["to"] ++ (data["cc"] || [])) end def visible_for_user?(activity, nil) do -- cgit v1.2.3 From dbc4e92509594139a906ce9546f442b531430c57 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 17 Jan 2019 23:19:15 +0000 Subject: activitypub: transmogrifier: do not clobber the addressing on relayed announcements --- lib/pleroma/web/activity_pub/transmogrifier.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 86d11c874..fa3abe3d8 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -451,7 +451,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do with actor <- get_actor(data), %User{} = actor <- User.get_or_fetch_by_ap_id(actor), {:ok, object} <- get_obj_helper(object_id) || fetch_obj_helper(object_id), - {:ok, activity, _object} <- ActivityPub.announce(actor, object, id, false) do + public <- ActivityPub.is_public?(data), + {:ok, activity, _object} <- ActivityPub.announce(actor, object, id, false, public) do {:ok, activity} else _e -> :error -- cgit v1.2.3 From 75a9b2a851eceb5308dbc9f1767d4bf37dcd8f77 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 17 Jan 2019 23:32:16 +0000 Subject: activitypub: add a match clause for objects, not just activities --- lib/pleroma/web/activity_pub/activity_pub.ex | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 92c5ce2ae..130c06028 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -798,6 +798,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end def is_public?(%Object{data: %{"type" => "Tombstone"}}), do: false + def is_public?(%Object{data: data}), do: is_public?(data) def is_public?(%Activity{data: data}), do: is_public?(data) def is_public?(data) do -- cgit v1.2.3 From 65bb9b2fba7560df7331645db9839305c47dad11 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Fri, 18 Jan 2019 09:30:16 +0300 Subject: [#491] Made full nicknames be preserved in user links text only in Bio. --- lib/pleroma/formatter.ex | 11 ++++++++--- lib/pleroma/user.ex | 15 ++++++++++++--- lib/pleroma/web/common_api/utils.ex | 14 ++++++++------ 3 files changed, 28 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index 024c6e117..37737853a 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -120,7 +120,7 @@ defmodule Pleroma.Formatter do end @doc "Adds the links to mentioned users" - def add_user_links({subs, text}, mentions) do + def add_user_links({subs, text}, mentions, options \\ []) do mentions = mentions |> Enum.sort_by(fn {name, _} -> -String.length(name) end) @@ -142,11 +142,16 @@ defmodule Pleroma.Formatter do ap_id end - full_match = String.trim_leading(match, "@") + nickname = + if options[:format] == :full do + User.full_nickname(match) + else + User.local_nickname(match) + end {uuid, "" <> - "@#{full_match}"} + "@#{nickname}"} end) {subs, uuid_text} diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index a52e536d3..2dc3c8d56 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -447,8 +447,7 @@ defmodule Pleroma.User do def get_by_nickname(nickname) do Repo.get_by(User, nickname: nickname) || if Regex.match?(~r(@#{Pleroma.Web.Endpoint.host()})i, nickname) do - [local_nickname, _] = String.split(nickname, "@") - Repo.get_by(User, nickname: local_nickname) + Repo.get_by(User, nickname: local_nickname(nickname)) end end @@ -990,7 +989,7 @@ defmodule Pleroma.User do end) bio - |> CommonUtils.format_input(mentions, tags, "text/plain") + |> CommonUtils.format_input(mentions, tags, "text/plain", user_links: [format: :full]) |> Formatter.emojify(emoji) end @@ -1041,6 +1040,16 @@ defmodule Pleroma.User do end end + def local_nickname(nickname_or_mention) do + nickname_or_mention + |> full_nickname() + |> String.split("@") + |> hd() + end + + def full_nickname(nickname_or_mention), + do: String.trim_leading(nickname_or_mention, "@") + def error_user(ap_id) do %User{ name: ap_id, diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index 7e30d224c..a36ab5c15 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -116,16 +116,18 @@ defmodule Pleroma.Web.CommonAPI.Utils do Enum.join([text | attachment_text], "
") end + def format_input(text, mentions, tags, format, options \\ []) + @doc """ Formatting text to plain text. """ - def format_input(text, mentions, tags, "text/plain") do + def format_input(text, mentions, tags, "text/plain", options) do text |> Formatter.html_escape("text/plain") |> String.replace(~r/\r?\n/, "
") |> (&{[], &1}).() |> Formatter.add_links() - |> Formatter.add_user_links(mentions) + |> Formatter.add_user_links(mentions, options[:user_links] || []) |> Formatter.add_hashtag_links(tags) |> Formatter.finalize() end @@ -133,24 +135,24 @@ defmodule Pleroma.Web.CommonAPI.Utils do @doc """ Formatting text to html. """ - def format_input(text, mentions, _tags, "text/html") do + def format_input(text, mentions, _tags, "text/html", options) do text |> Formatter.html_escape("text/html") |> (&{[], &1}).() - |> Formatter.add_user_links(mentions) + |> Formatter.add_user_links(mentions, options[:user_links] || []) |> Formatter.finalize() end @doc """ Formatting text to markdown. """ - def format_input(text, mentions, tags, "text/markdown") do + def format_input(text, mentions, tags, "text/markdown", options) do text |> Formatter.mentions_escape(mentions) |> Earmark.as_html!() |> Formatter.html_escape("text/html") |> (&{[], &1}).() - |> Formatter.add_user_links(mentions) + |> Formatter.add_user_links(mentions, options[:user_links] || []) |> Formatter.add_hashtag_links(tags) |> Formatter.finalize() end -- cgit v1.2.3 From ed8f55ab8eb292903cec8f7699aa6775cc304458 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Fri, 18 Jan 2019 10:35:45 +0300 Subject: [#477] User: FTS and trigram search results mixing (to handle misspelled requests). --- lib/pleroma/user.ex | 136 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 79 insertions(+), 57 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 8ae36416a..1d0bf1edf 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -679,48 +679,24 @@ defmodule Pleroma.User do end def search(query, resolve \\ false, for_user \\ nil) do - # strip the beginning @ off if there is a query + # Strip the beginning @ off if there is a query query = String.trim_leading(query, "@") - if resolve do - User.get_or_fetch_by_nickname(query) - end + if resolve, do: User.get_or_fetch_by_nickname(query) - processed_query = - query - |> String.replace(~r/\W+/, " ") - |> String.trim() - |> String.split() - |> Enum.map(&(&1 <> ":*")) - |> Enum.join(" | ") + fts_results = do_search(fts_search_subquery(query), for_user) - inner = - from( - u in User, - select_merge: %{ - search_rank: - fragment( - """ - ts_rank_cd( - setweight(to_tsvector('simple', regexp_replace(?, '\\W', ' ', 'g')), 'A') || - setweight(to_tsvector('simple', regexp_replace(coalesce(?, ''), '\\W', ' ', 'g')), 'B'), - to_tsquery('simple', ?), - 32 - ) - """, - u.nickname, - u.name, - ^processed_query - ) - }, - where: not is_nil(u.nickname) - ) + trigram_results = do_search(trigram_search_subquery(query), for_user) + + Enum.uniq_by(fts_results ++ trigram_results, & &1.id) + end + defp do_search(subquery, for_user, options \\ []) do q = from( - s in subquery(inner), + s in subquery(subquery), order_by: [desc: s.search_rank], - limit: 20 + limit: ^(options[:limit] || 20) ) results = @@ -728,35 +704,81 @@ defmodule Pleroma.User do |> Repo.all() |> Enum.filter(&(&1.search_rank > 0)) - weighted_results = - if for_user do - friends_ids = get_friends_ids(for_user) - followers_ids = get_followers_ids(for_user) + boost_search_results(results, for_user) + end - Enum.map( - results, - fn u -> - search_rank_coef = - cond do - u.id in friends_ids -> - 1.2 + defp fts_search_subquery(query) do + processed_query = + query + |> String.replace(~r/\W+/, " ") + |> String.trim() + |> String.split() + |> Enum.map(&(&1 <> ":*")) + |> Enum.join(" | ") + + from( + u in User, + select_merge: %{ + search_rank: + fragment( + """ + ts_rank_cd( + setweight(to_tsvector('simple', regexp_replace(?, '\\W', ' ', 'g')), 'A') || + setweight(to_tsvector('simple', regexp_replace(coalesce(?, ''), '\\W', ' ', 'g')), 'B'), + to_tsquery('simple', ?), + 32 + ) + """, + u.nickname, + u.name, + ^processed_query + ) + }, + where: not is_nil(u.nickname) + ) + end + + defp trigram_search_subquery(query) do + from( + u in User, + select_merge: %{ + search_rank: + fragment( + "similarity(?, ? || ' ' || coalesce(?, ''))", + ^query, + u.nickname, + u.name + ) + }, + where: not is_nil(u.nickname) + ) + end - u.id in followers_ids -> - 1.1 + defp boost_search_results(results, nil), do: results - true -> - 1 - end + defp boost_search_results(results, for_user) do + friends_ids = get_friends_ids(for_user) + followers_ids = get_followers_ids(for_user) - Map.put(u, :search_rank, u.search_rank * search_rank_coef) + Enum.map( + results, + fn u -> + search_rank_coef = + cond do + u.id in friends_ids -> + 1.2 + + u.id in followers_ids -> + 1.1 + + true -> + 1 end - ) - |> Enum.sort_by(&(-&1.search_rank)) - else - results - end - weighted_results + Map.put(u, :search_rank, u.search_rank * search_rank_coef) + end + ) + |> Enum.sort_by(&(-&1.search_rank)) end def blocks_import(%User{} = blocker, blocked_identifiers) when is_list(blocked_identifiers) do -- cgit v1.2.3 From 79e44042bc08cf69274008e408cac912ae693afe Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Fri, 18 Jan 2019 10:57:42 +0300 Subject: [#477] User trigram index adjustment. --- lib/pleroma/user.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 1d0bf1edf..eb4218ebe 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -744,7 +744,7 @@ defmodule Pleroma.User do select_merge: %{ search_rank: fragment( - "similarity(?, ? || ' ' || coalesce(?, ''))", + "similarity(?, trim(? || ' ' || coalesce(?, '')))", ^query, u.nickname, u.name -- cgit v1.2.3 From b108aeee082949e2e534f8bc406fdacb8924803d Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 20 Jan 2019 00:31:17 +0100 Subject: Make use of the indices. Indices in postgresql rely on operators, so they won't be used if you use only functions. --- lib/pleroma/user.ex | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index eb4218ebe..87815e11c 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -734,7 +734,16 @@ defmodule Pleroma.User do ^processed_query ) }, - where: not is_nil(u.nickname) + where: + fragment( + """ + (setweight(to_tsvector('simple', regexp_replace(?, '\\W', ' ', 'g')), 'A') || + setweight(to_tsvector('simple', regexp_replace(coalesce(?, ''), '\\W', ' ', 'g')), 'B')) @@ to_tsquery('simple', ?) + """, + u.nickname, + u.name, + ^processed_query + ) ) end @@ -750,7 +759,7 @@ defmodule Pleroma.User do u.name ) }, - where: not is_nil(u.nickname) + where: fragment("trim(? || ' ' || coalesce(?, '')) % ?", u.nickname, u.name, ^query) ) end -- cgit v1.2.3 From 8d06be35e0f1cb5caa2b638330c8bb03ad08a127 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 17 Nov 2018 15:51:02 +0000 Subject: activitypub: utils: add determine_explicit_mentions() and tests --- lib/pleroma/web/activity_pub/utils.ex | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index d2e457a68..d516818d9 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -25,6 +25,20 @@ defmodule Pleroma.Web.ActivityPub.Utils do Map.put(params, "actor", get_ap_id(params["actor"])) end + def determine_explicit_mentions(%{"tag" => tag} = _object) when is_list(tag) do + tag + |> Enum.filter(fn x -> is_map(x) end) + |> Enum.filter(fn x -> x["type"] == "Mention" end) + |> Enum.map(fn x -> x["href"] end) + end + + def determine_explicit_mentions(%{"tag" => tag} = object) when is_map(tag) do + Map.put(object, "tag", [tag]) + |> determine_explicit_mentions() + end + + def determine_explicit_mentions(_), do: [] + defp recipient_in_collection(ap_id, coll) when is_binary(coll), do: ap_id == coll defp recipient_in_collection(ap_id, coll) when is_list(coll), do: ap_id in coll defp recipient_in_collection(_, _), do: false -- cgit v1.2.3 From 681f40ee5c4de644c79f71bb6671c4c63b18e68a Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 17 Nov 2018 16:05:41 +0000 Subject: activitypub: transmogrifier: fix up to/cc addressing brain damage caused by mastodon-style explicit DMs --- lib/pleroma/web/activity_pub/transmogrifier.ex | 42 ++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index fa3abe3d8..e9a801cf5 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -93,12 +93,42 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do end end - def fix_addressing(map) do - map - |> fix_addressing_list("to") - |> fix_addressing_list("cc") - |> fix_addressing_list("bto") - |> fix_addressing_list("bcc") + def fix_explicit_addressing(%{"to" => to, "cc" => cc} = object, explicit_mentions) do + explicit_to = + to + |> Enum.filter(fn x -> x in explicit_mentions end) + + explicit_cc = + to + |> Enum.filter(fn x -> x not in explicit_mentions end) + + final_cc = + (cc ++ explicit_cc) + |> Enum.uniq() + + object + |> Map.put("to", explicit_to) + |> Map.put("cc", final_cc) + end + + def fix_explicit_addressing(object, _explicit_mentions), do: object + + def fix_addressing(object) do + object = + object + |> fix_addressing_list("to") + |> fix_addressing_list("cc") + |> fix_addressing_list("bto") + |> fix_addressing_list("bcc") + + explicit_mentions = + object + |> Utils.determine_explicit_mentions() + + explicit_mentions = explicit_mentions ++ ["https://www.w3.org/ns/activitystreams#Public"] + + object + |> fix_explicit_addressing(explicit_mentions) end def fix_actor(%{"attributedTo" => actor} = object) do -- cgit v1.2.3 From 75dfa1f0b07806908b11735afab3ba0dd3149659 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 17 Nov 2018 16:30:44 +0000 Subject: mastodon api: get_visibility(): DMs never have a cc list. --- lib/pleroma/web/mastodon_api/views/status_view.ex | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 7f5a52ea3..feabf54c6 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -231,6 +231,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do Enum.any?(to, &String.contains?(&1, "/followers")) -> "private" + length(cc) > 0 -> + "private" + true -> "direct" end -- cgit v1.2.3 From 9adc80afff5ea42e1773c6ada5e078ec6c1cadc8 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 23 Dec 2018 15:26:07 +0000 Subject: common api: set directMessage flag on our own posts --- lib/pleroma/web/common_api/common_api.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index 504670439..7084da6de 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -143,7 +143,7 @@ defmodule Pleroma.Web.CommonAPI do actor: user, context: context, object: object, - additional: %{"cc" => cc} + additional: %{"cc" => cc, "directMessage" => visibility == "direct"} }) res -- cgit v1.2.3 From ddae43eb43c5c63eeb0e93e60917b99b3ffb41d0 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 23 Dec 2018 15:27:08 +0000 Subject: activitypub: add is_private?/is_direct? helpers --- lib/pleroma/web/activity_pub/activity_pub.ex | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 130c06028..1fedfa854 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -805,6 +805,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do "https://www.w3.org/ns/activitystreams#Public" in (data["to"] ++ (data["cc"] || [])) end + def is_private?(activity) do + !is_public?(activity) && Enum.any?(activity.data["to"], &String.contains?(&1, "/followers")) + end + + def is_direct?(activity) do + !is_public?(activity) && !is_private?(activity) + end + def visible_for_user?(activity, nil) do is_public?(activity) end -- cgit v1.2.3 From 420651157becb8fac62e651d14376b6334316121 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 23 Dec 2018 15:35:49 +0000 Subject: transmogrifier: don't apply heuristics against messages which have `directMessage` set true --- lib/pleroma/web/activity_pub/transmogrifier.ex | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index e9a801cf5..5400aa657 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -113,14 +113,10 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do def fix_explicit_addressing(object, _explicit_mentions), do: object - def fix_addressing(object) do - object = - object - |> fix_addressing_list("to") - |> fix_addressing_list("cc") - |> fix_addressing_list("bto") - |> fix_addressing_list("bcc") + # if directMessage flag is set to true, leave the addressing alone + def fix_explicit_addressing(%{"directMessage" => true} = object), do: object + def fix_explicit_addressing(object) do explicit_mentions = object |> Utils.determine_explicit_mentions() @@ -131,6 +127,14 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do |> fix_explicit_addressing(explicit_mentions) end + def fix_addressing(object) do + object + |> fix_addressing_list("to") + |> fix_addressing_list("cc") + |> fix_addressing_list("bto") + |> fix_addressing_list("bcc") + end + def fix_actor(%{"attributedTo" => actor} = object) do object |> Map.put("actor", get_actor(%{"actor" => actor})) @@ -363,6 +367,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do data = Map.put(data, "actor", actor) |> fix_addressing + |> fix_explicit_addressing with nil <- Activity.get_create_activity_by_object_ap_id(object["id"]), %User{} = user <- User.get_or_fetch_by_ap_id(data["actor"]) do @@ -378,6 +383,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do additional: Map.take(data, [ "cc", + "directMessage", "id" ]) } -- cgit v1.2.3 From 7c9749f793aa0970a36742bf4177c1a9899b1ff4 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 23 Dec 2018 15:44:26 +0000 Subject: transmogrifier: slightly clean up fix_explicit_addressing pipeline --- lib/pleroma/web/activity_pub/transmogrifier.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 5400aa657..5d3feccfe 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -133,6 +133,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do |> fix_addressing_list("cc") |> fix_addressing_list("bto") |> fix_addressing_list("bcc") + |> fix_explicit_addressing end def fix_actor(%{"attributedTo" => actor} = object) do @@ -367,7 +368,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do data = Map.put(data, "actor", actor) |> fix_addressing - |> fix_explicit_addressing with nil <- Activity.get_create_activity_by_object_ap_id(object["id"]), %User{} = user <- User.get_or_fetch_by_ap_id(data["actor"]) do -- cgit v1.2.3 From aa37313416c155a37b40e09617eb2fe524edbf0b Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 20 Jan 2019 02:30:29 +0000 Subject: activitypub: short-circuit is_public?() with directMessage flag check --- lib/pleroma/web/activity_pub/activity_pub.ex | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 1fedfa854..68b684c4b 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -800,6 +800,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do def is_public?(%Object{data: %{"type" => "Tombstone"}}), do: false def is_public?(%Object{data: data}), do: is_public?(data) def is_public?(%Activity{data: data}), do: is_public?(data) + def is_public?(%{"directMessage" => true}), do: false def is_public?(data) do "https://www.w3.org/ns/activitystreams#Public" in (data["to"] ++ (data["cc"] || [])) @@ -809,6 +810,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do !is_public?(activity) && Enum.any?(activity.data["to"], &String.contains?(&1, "/followers")) end + def is_direct?(%Activity{data: %{"directMessage" => true}}), do: true + def is_direct?(%Object{data: %{"directMessage" => true}}), do: true + def is_direct?(activity) do !is_public?(activity) && !is_private?(activity) end -- cgit v1.2.3 From 5834b08fe77250d1dad0f2f6cd148f2fd8f85c09 Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 20 Jan 2019 10:57:49 +0100 Subject: Set custom similarity limit. --- lib/pleroma/user.ex | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 87815e11c..955808e28 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -686,7 +686,11 @@ defmodule Pleroma.User do fts_results = do_search(fts_search_subquery(query), for_user) - trigram_results = do_search(trigram_search_subquery(query), for_user) + {:ok, trigram_results} = + Repo.transaction(fn -> + Ecto.Adapters.SQL.query(Repo, "select set_limit(0.25)", []) + do_search(trigram_search_subquery(query), for_user) + end) Enum.uniq_by(fts_results ++ trigram_results, & &1.id) end -- cgit v1.2.3 From cf1f35a93a096311dee62ee5ac142a1bb3cfb844 Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 20 Jan 2019 13:00:46 +0100 Subject: Send delete event over Mastodon streaming api Closes #116 --- lib/pleroma/web/activity_pub/activity_pub.ex | 20 +++++++++++--------- lib/pleroma/web/streamer.ex | 9 +++++++++ 2 files changed, 20 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 130c06028..0431d62af 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -92,7 +92,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do def stream_out(activity) do public = "https://www.w3.org/ns/activitystreams#Public" - if activity.data["type"] in ["Create", "Announce"] do + if activity.data["type"] in ["Create", "Announce", "Delete"] do Pleroma.Web.Streamer.stream("user", activity) Pleroma.Web.Streamer.stream("list", activity) @@ -103,16 +103,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do Pleroma.Web.Streamer.stream("public:local", activity) end - activity.data["object"] - |> Map.get("tag", []) - |> Enum.filter(fn tag -> is_bitstring(tag) end) - |> Enum.map(fn tag -> Pleroma.Web.Streamer.stream("hashtag:" <> tag, activity) end) + if activity.data["type"] in ["Create"] do + activity.data["object"] + |> Map.get("tag", []) + |> Enum.filter(fn tag -> is_bitstring(tag) end) + |> Enum.map(fn tag -> Pleroma.Web.Streamer.stream("hashtag:" <> tag, activity) end) - if activity.data["object"]["attachment"] != [] do - Pleroma.Web.Streamer.stream("public:media", activity) + if activity.data["object"]["attachment"] != [] do + Pleroma.Web.Streamer.stream("public:media", activity) - if activity.local do - Pleroma.Web.Streamer.stream("public:local:media", activity) + if activity.local do + Pleroma.Web.Streamer.stream("public:local:media", activity) + end end end else diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index 3136b1b9d..978c77e57 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -205,6 +205,15 @@ defmodule Pleroma.Web.Streamer do end) end + def push_to_socket(topics, topic, %Activity{id: id, data: %{"type" => "Delete"}}) do + Enum.each(topics[topic] || [], fn socket -> + send( + socket.transport_pid, + {:text, %{event: "delete", payload: to_string(id)} |> Jason.encode!()} + ) + end) + end + def push_to_socket(topics, topic, item) do Enum.each(topics[topic] || [], fn socket -> # Get the current user so we have up-to-date blocks etc. -- cgit v1.2.3 From f94cc6d824cb2bdf4a41bc800d2bfc7d4f4dc23d Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Mon, 21 Jan 2019 01:16:41 +0100 Subject: Mix.Tasks.Pleroma.Instance: Generate signing_salt Closes: https://git.pleroma.social/pleroma/pleroma/issues/533 --- lib/mix/tasks/pleroma/instance.ex | 2 ++ lib/mix/tasks/pleroma/sample_config.eex | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/mix/tasks/pleroma/instance.ex b/lib/mix/tasks/pleroma/instance.ex index 0a2c891c0..1ba452275 100644 --- a/lib/mix/tasks/pleroma/instance.ex +++ b/lib/mix/tasks/pleroma/instance.ex @@ -105,6 +105,7 @@ defmodule Mix.Tasks.Pleroma.Instance do ) secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64) + signing_salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8) {web_push_public_key, web_push_private_key} = :crypto.generate_key(:ecdh, :prime256v1) result_config = @@ -120,6 +121,7 @@ defmodule Mix.Tasks.Pleroma.Instance do dbpass: dbpass, version: Pleroma.Mixfile.project() |> Keyword.get(:version), secret: secret, + signing_salt: signing_salt, web_push_public_key: Base.url_encode64(web_push_public_key, padding: false), web_push_private_key: Base.url_encode64(web_push_private_key, padding: false) ) diff --git a/lib/mix/tasks/pleroma/sample_config.eex b/lib/mix/tasks/pleroma/sample_config.eex index 740b9f8d1..1c935c0d8 100644 --- a/lib/mix/tasks/pleroma/sample_config.eex +++ b/lib/mix/tasks/pleroma/sample_config.eex @@ -7,7 +7,8 @@ use Mix.Config config :pleroma, Pleroma.Web.Endpoint, url: [host: "<%= domain %>", scheme: "https", port: <%= port %>], - secret_key_base: "<%= secret %>" + secret_key_base: "<%= secret %>", + signing_salt: "<%= signing_salt %>" config :pleroma, :instance, name: "<%= name %>", -- cgit v1.2.3 From b82c6dc53685ebd26c276eccc5ed915ddf81afa6 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Mon, 21 Jan 2019 06:29:05 +0100 Subject: =?UTF-8?q?Activity:=20all=5Fby=5Fobject=5Fap=5Fid/1=20=E2=86=92?= =?UTF-8?q?=20get=5Fall=5Fby=5Fobject=5Fap=5Fid/1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pleroma/activity.ex | 3 +-- lib/pleroma/web/activity_pub/utils.ex | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 353f9f6cd..e3edec475 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -67,8 +67,7 @@ defmodule Pleroma.Activity do ) end - # Wrong name plz fix thx - def all_by_object_ap_id(ap_id) do + def get_all_by_object_ap_id(ap_id) do Repo.all(all_by_object_ap_id_q(ap_id)) end diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index d2e457a68..cfbe6c857 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -198,7 +198,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do # Update activities that already had this. Could be done in a seperate process. # Alternatively, just don't do this and fetch the current object each time. Most # could probably be taken from cache. - relevant_activities = Activity.all_by_object_ap_id(id) + relevant_activities = Activity.get_all_by_object_ap_id(id) Enum.map(relevant_activities, fn activity -> new_activity_data = activity.data |> Map.put("object", object.data) -- cgit v1.2.3 From 75e4c8f0b21323f072f06e25e10762339abc6e3b Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Mon, 21 Jan 2019 06:15:05 +0100 Subject: =?UTF-8?q?Activity:=20all=5Fnon=5Fcreate=5Fby=5Fobject=5Fap=5Fid?= =?UTF-8?q?=5Fq=20=E2=86=92=20by=5Fobject=5Fap=5Fid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pleroma/activity.ex | 3 +-- lib/pleroma/object.ex | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index e3edec475..3be6fb82b 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -53,8 +53,7 @@ defmodule Pleroma.Activity do ) end - # Wrong name, returns all. - def all_non_create_by_object_ap_id_q(ap_id) do + def by_object_ap_id(ap_id) do from( activity in Activity, where: diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index ff5eb9b27..707a61f14 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -85,7 +85,7 @@ defmodule Pleroma.Object do def delete(%Object{data: %{"id" => id}} = object) do with {:ok, _obj} = swap_object_with_tombstone(object), - Repo.delete_all(Activity.all_non_create_by_object_ap_id_q(id)), + Repo.delete_all(Activity.by_object_ap_id(id)), {:ok, true} <- Cachex.del(:object_cache, "object:#{id}") do {:ok, object} end -- cgit v1.2.3 From 4ad5a0abb99eb90b1b1bebbad79acc67c16cf945 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Mon, 21 Jan 2019 06:39:00 +0100 Subject: =?UTF-8?q?Activity:=20all=5Fby=5Fobject=5Fap=5Fid=5Fq/1=20?= =?UTF-8?q?=E2=86=92=20create=5Fby=5Fobject=5Fap=5Fid/1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pleroma/activity.ex | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 3be6fb82b..588027de1 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -36,10 +36,7 @@ defmodule Pleroma.Activity do ) end - # TODO: - # Go through these and fix them everywhere. - # Wrong name, only returns create activities - def all_by_object_ap_id_q(ap_id) do + def create_by_object_ap_id(ap_id) do from( activity in Activity, where: @@ -67,7 +64,7 @@ defmodule Pleroma.Activity do end def get_all_by_object_ap_id(ap_id) do - Repo.all(all_by_object_ap_id_q(ap_id)) + Repo.all(create_by_object_ap_id(ap_id)) end def create_activity_by_object_id_query(ap_ids) do -- cgit v1.2.3 From f8ab1b7427e91ec1b7883e021836099226b56566 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Mon, 21 Jan 2019 06:46:47 +0100 Subject: =?UTF-8?q?Activity:=20get=5Fall=5Fby=5Fobject=5Fap=5Fid/1=20?= =?UTF-8?q?=E2=86=92=20get=5Fall=5Fcreate=5Fby=5Fobject=5Fap=5Fid/1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pleroma/activity.ex | 8 ++++---- lib/pleroma/web/activity_pub/utils.ex | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 588027de1..8c73d1fa0 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -63,10 +63,6 @@ defmodule Pleroma.Activity do ) end - def get_all_by_object_ap_id(ap_id) do - Repo.all(create_by_object_ap_id(ap_id)) - end - def create_activity_by_object_id_query(ap_ids) do from( activity in Activity, @@ -81,6 +77,10 @@ defmodule Pleroma.Activity do ) end + def get_all_create_by_object_ap_id(ap_id) do + Repo.all(create_by_object_ap_id(ap_id)) + end + def get_create_activity_by_object_ap_id(ap_id) when is_binary(ap_id) do create_activity_by_object_id_query([ap_id]) |> Repo.one() diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index cfbe6c857..4f4a54052 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -198,7 +198,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do # Update activities that already had this. Could be done in a seperate process. # Alternatively, just don't do this and fetch the current object each time. Most # could probably be taken from cache. - relevant_activities = Activity.get_all_by_object_ap_id(id) + relevant_activities = Activity.get_all_create_by_object_ap_id(id) Enum.map(relevant_activities, fn activity -> new_activity_data = activity.data |> Map.put("object", object.data) -- cgit v1.2.3 From 2fdbd4d137387d4d469d314b641070a9fdc0468c Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Mon, 21 Jan 2019 07:07:54 +0100 Subject: =?UTF-8?q?Activity:=20create=5Factivity=5Fby=5Fobject=5Fid=5Fquer?= =?UTF-8?q?y/1=20=E2=86=92=20create=5Fby=5Fobject=5Fap=5Fid/1=20when=20is?= =?UTF-8?q?=5Flist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pleroma/activity.ex | 4 ++-- lib/pleroma/web/mastodon_api/views/status_view.ex | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 8c73d1fa0..5c3b8fcc5 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -63,7 +63,7 @@ defmodule Pleroma.Activity do ) end - def create_activity_by_object_id_query(ap_ids) do + def create_by_object_ap_id(ap_ids) when is_list(ap_ids) do from( activity in Activity, where: @@ -82,7 +82,7 @@ defmodule Pleroma.Activity do end def get_create_activity_by_object_ap_id(ap_id) when is_binary(ap_id) do - create_activity_by_object_id_query([ap_id]) + create_by_object_ap_id(ap_id) |> Repo.one() end diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 7f5a52ea3..5e9c5c533 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -25,7 +25,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do nil end) |> Enum.filter(& &1) - |> Activity.create_activity_by_object_id_query() + |> Activity.create_by_object_ap_id() |> Repo.all() |> Enum.reduce(%{}, fn activity, acc -> Map.put(acc, activity.data["object"]["id"], activity) -- cgit v1.2.3 From 98c8184c1fc013fbd48bd78a2603c8e560038081 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Mon, 21 Jan 2019 07:14:20 +0100 Subject: =?UTF-8?q?Activity:=20get=5Fcreate=5Factivity=5Fby=5Fobject=5Fap?= =?UTF-8?q?=5Fid/1=20=E2=86=92=20get=5Fcreate=5Fby=5Fobject=5Fap=5Fid/1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pleroma/activity.ex | 27 +++++++++++----------- lib/pleroma/web/activity_pub/transmogrifier.ex | 4 ++-- lib/pleroma/web/common_api/utils.ex | 4 ++-- .../web/mastodon_api/mastodon_api_controller.ex | 11 ++++----- lib/pleroma/web/mastodon_api/views/status_view.ex | 4 ++-- lib/pleroma/web/ostatus/activity_representer.ex | 2 +- lib/pleroma/web/ostatus/handlers/note_handler.ex | 4 ++-- lib/pleroma/web/ostatus/ostatus.ex | 2 +- lib/pleroma/web/ostatus/ostatus_controller.ex | 3 +-- lib/pleroma/web/twitter_api/twitter_api.ex | 8 +++---- .../web/twitter_api/twitter_api_controller.ex | 4 ++-- lib/pleroma/web/twitter_api/views/activity_view.ex | 4 ++-- 12 files changed, 38 insertions(+), 39 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 5c3b8fcc5..81079ec3e 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -36,7 +36,7 @@ defmodule Pleroma.Activity do ) end - def create_by_object_ap_id(ap_id) do + def by_object_ap_id(ap_id) do from( activity in Activity, where: @@ -45,33 +45,34 @@ defmodule Pleroma.Activity do activity.data, activity.data, ^to_string(ap_id) - ), - where: fragment("(?)->>'type' = 'Create'", activity.data) + ) ) end - def by_object_ap_id(ap_id) do + + def create_by_object_ap_id(ap_ids) when is_list(ap_ids) do from( activity in Activity, where: fragment( - "coalesce((?)->'object'->>'id', (?)->>'object') = ?", + "coalesce((?)->'object'->>'id', (?)->>'object') = ANY(?)", activity.data, activity.data, - ^to_string(ap_id) - ) + ^ap_ids + ), + where: fragment("(?)->>'type' = 'Create'", activity.data) ) end - def create_by_object_ap_id(ap_ids) when is_list(ap_ids) do + def create_by_object_ap_id(ap_id) do from( activity in Activity, where: fragment( - "coalesce((?)->'object'->>'id', (?)->>'object') = ANY(?)", + "coalesce((?)->'object'->>'id', (?)->>'object') = ?", activity.data, activity.data, - ^ap_ids + ^to_string(ap_id) ), where: fragment("(?)->>'type' = 'Create'", activity.data) ) @@ -81,19 +82,19 @@ defmodule Pleroma.Activity do Repo.all(create_by_object_ap_id(ap_id)) end - def get_create_activity_by_object_ap_id(ap_id) when is_binary(ap_id) do + def get_create_by_object_ap_id(ap_id) when is_binary(ap_id) do create_by_object_ap_id(ap_id) |> Repo.one() end - def get_create_activity_by_object_ap_id(_), do: nil + def get_create_by_object_ap_id(_), do: nil def normalize(obj) when is_map(obj), do: Activity.get_by_ap_id(obj["id"]) def normalize(ap_id) when is_binary(ap_id), do: Activity.get_by_ap_id(ap_id) def normalize(_), do: nil def get_in_reply_to_activity(%Activity{data: %{"object" => %{"inReplyTo" => ap_id}}}) do - get_create_activity_by_object_ap_id(ap_id) + get_create_by_object_ap_id(ap_id) end def get_in_reply_to_activity(_), do: nil diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index fa3abe3d8..699a8957e 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -141,7 +141,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do case fetch_obj_helper(in_reply_to_id) do {:ok, replied_object} -> with %Activity{} = activity <- - Activity.get_create_activity_by_object_ap_id(replied_object.data["id"]) do + Activity.get_create_by_object_ap_id(replied_object.data["id"]) do object |> Map.put("inReplyTo", replied_object.data["id"]) |> Map.put("inReplyToAtomUri", object["inReplyToAtomUri"] || in_reply_to_id) @@ -334,7 +334,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do Map.put(data, "actor", actor) |> fix_addressing - with nil <- Activity.get_create_activity_by_object_ap_id(object["id"]), + with nil <- Activity.get_create_by_object_ap_id(object["id"]), %User{} = user <- User.get_or_fetch_by_ap_id(data["actor"]) do object = fix_object(data["object"]) diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index a36ab5c15..a0f59d900 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -14,13 +14,13 @@ defmodule Pleroma.Web.CommonAPI.Utils do # This is a hack for twidere. def get_by_id_or_ap_id(id) do - activity = Repo.get(Activity, id) || Activity.get_create_activity_by_object_ap_id(id) + activity = Repo.get(Activity, id) || Activity.get_create_by_object_ap_id(id) activity && if activity.data["type"] == "Create" do activity else - Activity.get_create_activity_by_object_ap_id(activity.data["object"]) + Activity.get_create_by_object_ap_id(activity.data["object"]) end end diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 882d336be..f4736fcb5 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -377,7 +377,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def unreblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do with {:ok, _unannounce, %{data: %{"id" => id}}} <- CommonAPI.unrepeat(ap_id_or_id, user), - %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do + %Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do conn |> put_view(StatusView) |> try_render("status.json", %{activity: activity, for: user, as: :activity}) @@ -386,7 +386,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def fav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do with {:ok, _fav, %{data: %{"id" => id}}} <- CommonAPI.favorite(ap_id_or_id, user), - %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do + %Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do conn |> put_view(StatusView) |> try_render("status.json", %{activity: activity, for: user, as: :activity}) @@ -395,7 +395,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def unfav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do with {:ok, _, _, %{data: %{"id" => id}}} <- CommonAPI.unfavorite(ap_id_or_id, user), - %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do + %Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do conn |> put_view(StatusView) |> try_render("status.json", %{activity: activity, for: user, as: :activity}) @@ -743,8 +743,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do fetched = if Regex.match?(~r/https?:/, query) do with {:ok, object} <- ActivityPub.fetch_object_from_id(query), - %Activity{} = activity <- - Activity.get_create_activity_by_object_ap_id(object.data["id"]), + %Activity{} = activity <- Activity.get_create_by_object_ap_id(object.data["id"]), true <- ActivityPub.visible_for_user?(activity, user) do [activity] else @@ -1138,7 +1137,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def render_notification(user, %{id: id, activity: activity, inserted_at: created_at} = _params) do actor = User.get_cached_by_ap_id(activity.data["actor"]) - parent_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) + parent_activity = Activity.get_create_by_object_ap_id(activity.data["object"]) mastodon_type = Activity.mastodon_notification_type(activity) response = %{ diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 5e9c5c533..74c875c29 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -64,7 +64,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do user = get_user(activity.data["actor"]) created_at = Utils.to_masto_date(activity.data["published"]) - reblogged = Activity.get_create_activity_by_object_ap_id(object) + reblogged = Activity.get_create_by_object_ap_id(object) reblogged = render("status.json", Map.put(opts, :activity, reblogged)) mentions = @@ -209,7 +209,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do def get_reply_to(%{data: %{"object" => object}}, _) do if object["inReplyTo"] && object["inReplyTo"] != "" do - Activity.get_create_activity_by_object_ap_id(object["inReplyTo"]) + Activity.get_create_by_object_ap_id(object["inReplyTo"]) else nil end diff --git a/lib/pleroma/web/ostatus/activity_representer.ex b/lib/pleroma/web/ostatus/activity_representer.ex index 94b1a7ad1..3d41fc708 100644 --- a/lib/pleroma/web/ostatus/activity_representer.ex +++ b/lib/pleroma/web/ostatus/activity_representer.ex @@ -183,7 +183,7 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do _in_reply_to = get_in_reply_to(activity.data) author = if with_author, do: [{:author, UserRepresenter.to_simple_form(user)}], else: [] - retweeted_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) + retweeted_activity = Activity.get_create_by_object_ap_id(activity.data["object"]) retweeted_user = User.get_cached_by_ap_id(retweeted_activity.data["actor"]) retweeted_xml = to_simple_form(retweeted_activity, retweeted_user, true) diff --git a/lib/pleroma/web/ostatus/handlers/note_handler.ex b/lib/pleroma/web/ostatus/handlers/note_handler.ex index 5aeed46f0..c5b3e8d97 100644 --- a/lib/pleroma/web/ostatus/handlers/note_handler.ex +++ b/lib/pleroma/web/ostatus/handlers/note_handler.ex @@ -86,7 +86,7 @@ defmodule Pleroma.Web.OStatus.NoteHandler do end def fetch_replied_to_activity(entry, inReplyTo) do - with %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(inReplyTo) do + with %Activity{} = activity <- Activity.get_create_by_object_ap_id(inReplyTo) do activity else _e -> @@ -103,7 +103,7 @@ defmodule Pleroma.Web.OStatus.NoteHandler do # TODO: Clean this up a bit. def handle_note(entry, doc \\ nil) do with id <- XML.string_from_xpath("//id", entry), - activity when is_nil(activity) <- Activity.get_create_activity_by_object_ap_id(id), + activity when is_nil(activity) <- Activity.get_create_by_object_ap_id(id), [author] <- :xmerl_xpath.string('//author[1]', doc), {:ok, actor} <- OStatus.find_make_or_update_user(author), content_html <- OStatus.get_content(entry), diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex index bb28cd786..a3155b79d 100644 --- a/lib/pleroma/web/ostatus/ostatus.ex +++ b/lib/pleroma/web/ostatus/ostatus.ex @@ -148,7 +148,7 @@ defmodule Pleroma.Web.OStatus do Logger.debug("Trying to get entry from db") with id when not is_nil(id) <- string_from_xpath("//activity:object[1]/id", entry), - %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do + %Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do {:ok, activity} else _ -> diff --git a/lib/pleroma/web/ostatus/ostatus_controller.ex b/lib/pleroma/web/ostatus/ostatus_controller.ex index 332cbef0e..ce022bcc1 100644 --- a/lib/pleroma/web/ostatus/ostatus_controller.ex +++ b/lib/pleroma/web/ostatus/ostatus_controller.ex @@ -90,8 +90,7 @@ defmodule Pleroma.Web.OStatus.OStatusController do ActivityPubController.call(conn, :object) else with id <- o_status_url(conn, :object, uuid), - {_, %Activity{} = activity} <- - {:activity, Activity.get_create_activity_by_object_ap_id(id)}, + {_, %Activity{} = activity} <- {:activity, Activity.get_create_by_object_ap_id(id)}, {_, true} <- {:public?, ActivityPub.is_public?(activity)}, %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do case get_format(conn) do diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index 7a63724f1..7d00c01a1 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -70,14 +70,14 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do def repeat(%User{} = user, ap_id_or_id) do with {:ok, _announce, %{data: %{"id" => id}}} <- CommonAPI.repeat(ap_id_or_id, user), - %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do + %Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do {:ok, activity} end end def unrepeat(%User{} = user, ap_id_or_id) do with {:ok, _unannounce, %{data: %{"id" => id}}} <- CommonAPI.unrepeat(ap_id_or_id, user), - %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do + %Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do {:ok, activity} end end @@ -92,14 +92,14 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do def fav(%User{} = user, ap_id_or_id) do with {:ok, _fav, %{data: %{"id" => id}}} <- CommonAPI.favorite(ap_id_or_id, user), - %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do + %Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do {:ok, activity} end end def unfav(%User{} = user, ap_id_or_id) do with {:ok, _unfav, _fav, %{data: %{"id" => id}}} <- CommonAPI.unfavorite(ap_id_or_id, user), - %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do + %Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do {:ok, activity} end end diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index ede079963..8c9060cf2 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -330,12 +330,12 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end def get_by_id_or_ap_id(id) do - activity = Repo.get(Activity, id) || Activity.get_create_activity_by_object_ap_id(id) + activity = Repo.get(Activity, id) || Activity.get_create_by_object_ap_id(id) if activity.data["type"] == "Create" do activity else - Activity.get_create_activity_by_object_ap_id(activity.data["object"]) + Activity.get_create_by_object_ap_id(activity.data["object"]) end end diff --git a/lib/pleroma/web/twitter_api/views/activity_view.ex b/lib/pleroma/web/twitter_api/views/activity_view.ex index 03708d84c..5eb06a26e 100644 --- a/lib/pleroma/web/twitter_api/views/activity_view.ex +++ b/lib/pleroma/web/twitter_api/views/activity_view.ex @@ -168,7 +168,7 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do def render("activity.json", %{activity: %{data: %{"type" => "Announce"}} = activity} = opts) do user = get_user(activity.data["actor"], opts) created_at = activity.data["published"] |> Utils.date_to_asctime() - announced_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) + announced_activity = Activity.get_create_by_object_ap_id(activity.data["object"]) text = "#{user.nickname} retweeted a status." @@ -192,7 +192,7 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do def render("activity.json", %{activity: %{data: %{"type" => "Like"}} = activity} = opts) do user = get_user(activity.data["actor"], opts) - liked_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) + liked_activity = Activity.get_create_by_object_ap_id(activity.data["object"]) liked_activity_id = if liked_activity, do: liked_activity.id, else: nil created_at = -- cgit v1.2.3 From 7390192c03248ff18eff19d555f28300a7b07e09 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Mon, 21 Jan 2019 07:37:45 +0100 Subject: Activity: mix format (2 empty lines) --- lib/pleroma/activity.ex | 1 - 1 file changed, 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 81079ec3e..fe017df3b 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -49,7 +49,6 @@ defmodule Pleroma.Activity do ) end - def create_by_object_ap_id(ap_ids) when is_list(ap_ids) do from( activity in Activity, -- cgit v1.2.3 From aa480f4a8b46f24a07491228462b4318ca25eda7 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Mon, 21 Jan 2019 14:16:51 +0300 Subject: [#530] Prevents user `info` from being overwritten because of race conditions and non-partial update of embed (in WebFinger.ensure_keys_present and other places). --- lib/pleroma/web/activity_pub/activity_pub.ex | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 0431d62af..32c08c9d2 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -140,8 +140,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do additional ), {:ok, activity} <- insert(create_data, local), - :ok <- maybe_federate(activity), - {:ok, _actor} <- User.increase_note_count(actor) do + # Changing note count prior to federation in order not to reload `actor` (potentially updated by federator) + {:ok, _actor} <- User.increase_note_count(actor), + :ok <- maybe_federate(activity) do {:ok, activity} end end @@ -288,8 +289,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do with {:ok, _} <- Object.delete(object), {:ok, activity} <- insert(data, local), - :ok <- maybe_federate(activity), - {:ok, _actor} <- User.decrease_note_count(user) do + # Changing note count prior to federation in order not to reload `actor` (potentially updated by federator) + {:ok, _actor} <- User.decrease_note_count(user), + :ok <- maybe_federate(activity) do {:ok, activity} end end -- cgit v1.2.3 From a4d3fec8a71241d5c40fa76e33f15fa217154600 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Mon, 21 Jan 2019 14:52:41 +0300 Subject: [#502] Code comments update. --- lib/pleroma/web/activity_pub/activity_pub.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 32c08c9d2..fd026a047 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -140,7 +140,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do additional ), {:ok, activity} <- insert(create_data, local), - # Changing note count prior to federation in order not to reload `actor` (potentially updated by federator) + # Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info {:ok, _actor} <- User.increase_note_count(actor), :ok <- maybe_federate(activity) do {:ok, activity} @@ -289,7 +289,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do with {:ok, _} <- Object.delete(object), {:ok, activity} <- insert(data, local), - # Changing note count prior to federation in order not to reload `actor` (potentially updated by federator) + # Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info {:ok, _actor} <- User.decrease_note_count(user), :ok <- maybe_federate(activity) do {:ok, activity} -- cgit v1.2.3 From 97412d9f94ed55caecb7a35e1f95aef7bdf0db19 Mon Sep 17 00:00:00 2001 From: href Date: Mon, 21 Jan 2019 14:42:16 +0100 Subject: S3 Namespace --- lib/pleroma/uploaders/s3.ex | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/uploaders/s3.ex b/lib/pleroma/uploaders/s3.ex index 108cf06b5..fbd89616c 100644 --- a/lib/pleroma/uploaders/s3.ex +++ b/lib/pleroma/uploaders/s3.ex @@ -9,12 +9,20 @@ defmodule Pleroma.Uploaders.S3 do # The file name is re-encoded with S3's constraints here to comply with previous links with less strict filenames def get_file(file) do config = Pleroma.Config.get([__MODULE__]) + bucket = Keyword.fetch!(config, :bucket) + + bucket_with_namespace = + if namespace = Keyword.get(config, :bucket_namespace) do + namespace <> ":" <> bucket + else + bucket + end {:ok, {:url, Path.join([ Keyword.fetch!(config, :public_endpoint), - Keyword.fetch!(config, :bucket), + bucket_with_namespace, strict_encode(URI.decode(file)) ])}} end -- cgit v1.2.3 From 99763999c19bfb2a5d8a10af98ff3c54d2c929ce Mon Sep 17 00:00:00 2001 From: href Date: Mon, 21 Jan 2019 15:17:24 +0100 Subject: reverse_proxy - always override plug's cache-control --- lib/pleroma/reverse_proxy.ex | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/reverse_proxy.ex b/lib/pleroma/reverse_proxy.ex index a3846c3bb..a25b5ea4e 100644 --- a/lib/pleroma/reverse_proxy.ex +++ b/lib/pleroma/reverse_proxy.ex @@ -275,11 +275,24 @@ defmodule Pleroma.ReverseProxy do defp build_resp_cache_headers(headers, _opts) do has_cache? = Enum.any?(headers, fn {k, _} -> k in @resp_cache_headers end) - - if has_cache? do - headers - else - List.keystore(headers, "cache-control", 0, {"cache-control", @default_cache_control_header}) + has_cache_control? = List.keymember?(headers, "cache-control", 0) + + cond do + has_cache? && has_cache_control? -> + headers + + has_cache? -> + # There's caching header present but no cache-control -- we need to explicitely override it to public + # as Plug defaults to "max-age=0, private, must-revalidate" + List.keystore(headers, "cache-control", 0, {"cache-control", "public"}) + + true -> + List.keystore( + headers, + "cache-control", + 0, + {"cache-control", @default_cache_control_header} + ) end end -- cgit v1.2.3 From f9a326909979959d6cb43f66177045bb2adccbf4 Mon Sep 17 00:00:00 2001 From: href Date: Mon, 21 Jan 2019 22:44:14 +0100 Subject: Uploader callback controller --- lib/pleroma/uploaders/uploader.ex | 37 ++++++++++++++++++++++++++++++---- lib/pleroma/web/router.ex | 5 +++++ lib/pleroma/web/uploader_controller.ex | 25 +++++++++++++++++++++++ 3 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 lib/pleroma/web/uploader_controller.ex (limited to 'lib') diff --git a/lib/pleroma/uploaders/uploader.ex b/lib/pleroma/uploaders/uploader.ex index 0959d7a3e..ce83cbbbc 100644 --- a/lib/pleroma/uploaders/uploader.ex +++ b/lib/pleroma/uploaders/uploader.ex @@ -27,18 +27,47 @@ defmodule Pleroma.Uploaders.Uploader do This allows to correctly proxy or redirect requests to the backend, while allowing to migrate backends without breaking any URL. * `{url, url :: String.t}` to bypass `get_file/2` and use the `url` directly in the activity. * `{:error, String.t}` error information if the file failed to be saved to the backend. + * `:wait_callback` will wait for an http post request at `/api/pleroma/upload_callback/:upload_path` and call the uploader's `http_callback/3` method. """ + @type file_spec :: {:file | :url, String.t()} @callback put_file(Pleroma.Upload.t()) :: - :ok | {:ok, {:file | :url, String.t()}} | {:error, String.t()} + :ok | {:ok, file_spec()} | {:error, String.t()} | :wait_callback + + @callback http_callback(Plug.Conn.t(), Map.t()) :: + {:ok, Plug.Conn.t()} + | {:ok, Plug.Conn.t(), file_spec()} + | {:error, Plug.Conn.t(), String.t()} + @optional_callbacks http_callback: 2 + + @spec put_file(module(), Pleroma.Upload.t()) :: {:ok, file_spec()} | {:error, String.t()} - @spec put_file(module(), Pleroma.Upload.t()) :: - {:ok, {:file | :url, String.t()}} | {:error, String.t()} def put_file(uploader, upload) do case uploader.put_file(upload) do :ok -> {:ok, {:file, upload.path}} - other -> other + :wait_callback -> handle_callback(uploader, upload) + {:ok, _} = ok -> ok + {:error, _} = error -> error + end + end + + defp handle_callback(uploader, upload) do + :global.register_name({__MODULE__, upload.path}, self()) + + receive do + {__MODULE__, pid, conn, params} -> + case uploader.http_callback(conn, params) do + {:ok, conn, ok} -> + send(pid, {__MODULE__, conn}) + {:ok, ok} + + {:error, conn, error} -> + send(pid, {__MODULE__, conn}) + {:error, error} + end + after + 30_000 -> {:error, "Uploader callback timeout"} end end end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 7a0c9fd25..69ab58c6a 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -107,6 +107,11 @@ defmodule Pleroma.Web.Router do get("/captcha", UtilController, :captcha) end + scope "/api/pleroma", Pleroma.Web do + pipe_through(:pleroma_api) + post("/uploader_callback/:upload_path", UploaderController, :callback) + end + scope "/api/pleroma/admin", Pleroma.Web.AdminAPI do pipe_through(:admin_api) delete("/user", AdminAPIController, :user_delete) diff --git a/lib/pleroma/web/uploader_controller.ex b/lib/pleroma/web/uploader_controller.ex new file mode 100644 index 000000000..6c28d1197 --- /dev/null +++ b/lib/pleroma/web/uploader_controller.ex @@ -0,0 +1,25 @@ +defmodule Pleroma.Web.UploaderController do + use Pleroma.Web, :controller + + alias Pleroma.Uploaders.Uploader + + def callback(conn, params = %{"upload_path" => upload_path}) do + process_callback(conn, :global.whereis_name({Uploader, upload_path}), params) + end + + def callbacks(conn, _) do + send_resp(conn, 400, "bad request") + end + + defp process_callback(conn, pid, params) when is_pid(pid) do + send(pid, {Uploader, self(), conn, params}) + + receive do + {Uploader, conn} -> conn + end + end + + defp process_callback(conn, _, _) do + send_resp(conn, 400, "bad request") + end +end -- cgit v1.2.3 From e460820fcfcdc68c3e2a43ee69d587ca261324f8 Mon Sep 17 00:00:00 2001 From: rinpatch Date: Tue, 22 Jan 2019 10:54:11 +0300 Subject: Add get_by_id to activity.ex --- lib/pleroma/activity.ex | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 353f9f6cd..8fd0311d2 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -36,6 +36,10 @@ defmodule Pleroma.Activity do ) end + def get_by_id(id) do + Repo.get(Activity, id) + end + # TODO: # Go through these and fix them everywhere. # Wrong name, only returns create activities -- cgit v1.2.3 From 34d59e40086ad8adc020bac6d23ab2aa835f267b Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Tue, 22 Jan 2019 17:12:53 +0300 Subject: [#502] Fixed User.active_local_user_query to return users with nil or missing `info.deactivated`. Adjusted test. --- lib/pleroma/user.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 06084b117..18137106e 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -901,7 +901,7 @@ defmodule Pleroma.User do def active_local_user_query do from( u in local_user_query(), - where: fragment("?->'deactivated' @> 'false'", u.info) + where: fragment("not (?->'deactivated' @> 'true')", u.info) ) end -- cgit v1.2.3 From 28d77e373cbaf0908f86973a873c9bfd6c3221cb Mon Sep 17 00:00:00 2001 From: href Date: Wed, 9 Jan 2019 16:08:24 +0100 Subject: Flake Ids for Users and Activities --- lib/pleroma/PasswordResetToken.ex | 2 +- lib/pleroma/activity.ex | 1 + lib/pleroma/application.ex | 1 + lib/pleroma/filter.ex | 2 +- lib/pleroma/flake_id.ex | 181 +++++++++++++++++++++ lib/pleroma/list.ex | 2 +- lib/pleroma/notification.ex | 6 +- lib/pleroma/user.ex | 2 + lib/pleroma/web/activity_pub/transmogrifier.ex | 5 - lib/pleroma/web/activity_pub/views/user_view.ex | 4 +- lib/pleroma/web/oauth/authorization.ex | 2 +- lib/pleroma/web/oauth/token.ex | 2 +- lib/pleroma/web/push/subscription.ex | 2 +- .../web/twitter_api/twitter_api_controller.ex | 24 +-- .../web/websub/websub_client_subscription.ex | 2 +- 15 files changed, 209 insertions(+), 29 deletions(-) create mode 100644 lib/pleroma/flake_id.ex (limited to 'lib') diff --git a/lib/pleroma/PasswordResetToken.ex b/lib/pleroma/PasswordResetToken.ex index 1dccdadae..c3c0384d2 100644 --- a/lib/pleroma/PasswordResetToken.ex +++ b/lib/pleroma/PasswordResetToken.ex @@ -10,7 +10,7 @@ defmodule Pleroma.PasswordResetToken do alias Pleroma.{User, PasswordResetToken, Repo} schema "password_reset_tokens" do - belongs_to(:user, User) + belongs_to(:user, User, type: Pleroma.FlakeId) field(:token, :string) field(:used, :boolean, default: false) diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 8fd0311d2..d907791b5 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -8,6 +8,7 @@ defmodule Pleroma.Activity do import Ecto.Query @type t :: %__MODULE__{} + @primary_key {:id, Pleroma.FlakeId, autogenerate: true} # https://github.com/tootsuite/mastodon/blob/master/app/models/notification.rb#L19 @mastodon_notification_types %{ diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index ad2797209..47c0e5b68 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -99,6 +99,7 @@ defmodule Pleroma.Application do ], id: :cachex_idem ), + worker(Pleroma.FlakeId, []), worker(Pleroma.Web.Federator.RetryQueue, []), worker(Pleroma.Web.Federator, []), worker(Pleroma.Stats, []), diff --git a/lib/pleroma/filter.ex b/lib/pleroma/filter.ex index df5374a5c..308bd70e1 100644 --- a/lib/pleroma/filter.ex +++ b/lib/pleroma/filter.ex @@ -8,7 +8,7 @@ defmodule Pleroma.Filter do alias Pleroma.{User, Repo} schema "filters" do - belongs_to(:user, User) + belongs_to(:user, User, type: Pleroma.FlakeId) field(:filter_id, :integer) field(:hide, :boolean, default: false) field(:whole_word, :boolean, default: true) diff --git a/lib/pleroma/flake_id.ex b/lib/pleroma/flake_id.ex new file mode 100644 index 000000000..3c72807ca --- /dev/null +++ b/lib/pleroma/flake_id.ex @@ -0,0 +1,181 @@ +defmodule Pleroma.FlakeId do + @moduledoc """ + Flake is a decentralized, k-ordered id generation service. + + Adapted from: + + * [flaky](https://github.com/nirvana/flaky), released under the terms of the Truly Free License, + * [Flake](https://github.com/boundary/flake), Copyright 2012, Boundary, Apache License, Version 2.0 + """ + + @type t :: binary + + @behaviour Ecto.Type + use GenServer + require Logger + alias __MODULE__ + import Kernel, except: [to_string: 1] + + defstruct node: nil, time: 0, sq: 0 + + @doc "Converts a binary Flake to a String" + def to_string(<<0::integer-size(64), id::integer-size(64)>>) do + Kernel.to_string(id) + end + + def to_string(flake = <<_::integer-size(64), _::integer-size(48), _::integer-size(16)>>) do + encode_base62(flake) + end + + def to_string(s), do: s + + def from_string(<>) do + <<0::integer-size(64), id::integer-size(64)>> + end + + for i <- [-1, 0] do + def from_string(unquote(i)), do: <<0::integer-size(128)>> + def from_string(unquote(Kernel.to_string(i))), do: <<0::integer-size(128)>> + end + + def from_string(string) when is_binary(string) and byte_size(string) < 18 do + case Integer.parse(string) do + {id, _} -> <<0::integer-size(64), id::integer-size(64)>> + _ -> nil + end + end + + def from_string(string) do + string |> decode_base62 |> from_integer + end + + def to_integer(<>), do: integer + + def from_integer(integer) do + <<_time::integer-size(64), _node::integer-size(48), _seq::integer-size(16)>> = + <> + end + + @doc "Generates a Flake" + @spec get :: binary + def get, do: to_string(:gen_server.call(:flake, :get)) + + # -- Ecto.Type API + @impl Ecto.Type + def type, do: :uuid + + @impl Ecto.Type + def cast(value) do + {:ok, FlakeId.to_string(value)} + end + + @impl Ecto.Type + def load(value) do + {:ok, FlakeId.to_string(value)} + end + + @impl Ecto.Type + def dump(value) do + {:ok, FlakeId.from_string(value)} + end + + def autogenerate(), do: get() + + # -- GenServer API + def start_link do + :gen_server.start_link({:local, :flake}, __MODULE__, [], []) + end + + @impl GenServer + def init([]) do + {:ok, %FlakeId{node: mac(), time: time()}} + end + + @impl GenServer + def handle_call(:get, _from, state) do + {flake, new_state} = get(time(), state) + {:reply, flake, new_state} + end + + # Matches when the calling time is the same as the state time. Incr. sq + defp get(time, %FlakeId{time: time, node: node, sq: seq}) do + new_state = %FlakeId{time: time, node: node, sq: seq + 1} + {gen_flake(new_state), new_state} + end + + # Matches when the times are different, reset sq + defp get(newtime, %FlakeId{time: time, node: node}) when newtime > time do + new_state = %FlakeId{time: newtime, node: node, sq: 0} + {gen_flake(new_state), new_state} + end + + # Error when clock is running backwards + defp get(newtime, %FlakeId{time: time}) when newtime < time do + {:error, :clock_running_backwards} + end + + defp gen_flake(%FlakeId{time: time, node: node, sq: seq}) do + <> + end + + defp nthchar_base62(n) when n <= 9, do: ?0 + n + defp nthchar_base62(n) when n <= 35, do: ?A + n - 10 + defp nthchar_base62(n), do: ?a + n - 36 + + defp encode_base62(<>) do + integer + |> encode_base62([]) + |> List.to_string() + end + + defp encode_base62(int, acc) when int < 0, do: encode_base62(-int, acc) + defp encode_base62(int, []) when int == 0, do: '0' + defp encode_base62(int, acc) when int == 0, do: acc + + defp encode_base62(int, acc) do + r = rem(int, 62) + id = div(int, 62) + acc = [nthchar_base62(r) | acc] + encode_base62(id, acc) + end + + defp decode_base62(s) do + decode_base62(String.to_charlist(s), 0) + end + + defp decode_base62([c | cs], acc) when c >= ?0 and c <= ?9, + do: decode_base62(cs, 62 * acc + (c - ?0)) + + defp decode_base62([c | cs], acc) when c >= ?A and c <= ?Z, + do: decode_base62(cs, 62 * acc + (c - ?A + 10)) + + defp decode_base62([c | cs], acc) when c >= ?a and c <= ?z, + do: decode_base62(cs, 62 * acc + (c - ?a + 36)) + + defp decode_base62([], acc), do: acc + + defp time do + {mega_seconds, seconds, micro_seconds} = :erlang.timestamp() + 1_000_000_000 * mega_seconds + seconds * 1000 + :erlang.trunc(micro_seconds / 1000) + end + + defp mac do + {:ok, addresses} = :inet.getifaddrs() + + ifaces_with_mac = + Enum.reduce(addresses, [], fn {iface, attrs}, acc -> + if attrs[:hwaddr], do: [iface | acc], else: acc + end) + + iface = Enum.at(ifaces_with_mac, :rand.uniform(length(ifaces_with_mac)) - 1) + mac(iface) + end + + defp mac(name) do + {:ok, addresses} = :inet.getifaddrs() + proplist = :proplists.get_value(name, addresses) + hwaddr = Enum.take(:proplists.get_value(:hwaddr, proplist), 6) + <> = :binary.list_to_bin(hwaddr) + worker + end +end diff --git a/lib/pleroma/list.ex b/lib/pleroma/list.ex index a75dc006e..ca66c6916 100644 --- a/lib/pleroma/list.ex +++ b/lib/pleroma/list.ex @@ -8,7 +8,7 @@ defmodule Pleroma.List do alias Pleroma.{User, Repo, Activity} schema "lists" do - belongs_to(:user, Pleroma.User) + belongs_to(:user, User, type: Pleroma.FlakeId) field(:title, :string) field(:following, {:array, :string}, default: []) diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index c7d01f63b..2c8f60f19 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -9,8 +9,8 @@ defmodule Pleroma.Notification do schema "notifications" do field(:seen, :boolean, default: false) - belongs_to(:user, Pleroma.User) - belongs_to(:activity, Pleroma.Activity) + belongs_to(:user, User, type: Pleroma.FlakeId) + belongs_to(:activity, Activity, type: Pleroma.FlakeId) timestamps() end @@ -96,7 +96,7 @@ defmodule Pleroma.Notification do end end - def create_notifications(%Activity{id: _, data: %{"to" => _, "type" => type}} = activity) + def create_notifications(%Activity{data: %{"to" => _, "type" => type}} = activity) when type in ["Create", "Like", "Announce", "Follow"] do users = get_notified_from_activity(activity) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 18137106e..b006f9f19 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -17,6 +17,8 @@ defmodule Pleroma.User do @type t :: %__MODULE__{} + @primary_key {:id, Pleroma.FlakeId, autogenerate: true} + @email_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])?)*$/ @strict_local_nickname_regex ~r/^[a-zA-Z\d]+$/ diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 5d3feccfe..e646de608 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -900,15 +900,10 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do maybe_retire_websub(user.ap_id) - # Only do this for recent activties, don't go through the whole db. - # Only look at the last 1000 activities. - since = (Repo.aggregate(Activity, :max, :id) || 0) - 1_000 - q = from( a in Activity, where: ^old_follower_address in a.recipients, - where: a.id > ^since, update: [ set: [ recipients: diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex index fe8248107..dcf681b6d 100644 --- a/lib/pleroma/web/activity_pub/views/user_view.ex +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -160,7 +160,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do "partOf" => iri, "totalItems" => info.note_count, "orderedItems" => collection, - "next" => "#{iri}?max_id=#{min_id - 1}" + "next" => "#{iri}?max_id=#{min_id}" } if max_qid == nil do @@ -207,7 +207,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do "partOf" => iri, "totalItems" => -1, "orderedItems" => collection, - "next" => "#{iri}?max_id=#{min_id - 1}" + "next" => "#{iri}?max_id=#{min_id}" } if max_qid == nil do diff --git a/lib/pleroma/web/oauth/authorization.ex b/lib/pleroma/web/oauth/authorization.ex index cc4b74bc5..f8c65602d 100644 --- a/lib/pleroma/web/oauth/authorization.ex +++ b/lib/pleroma/web/oauth/authorization.ex @@ -14,7 +14,7 @@ defmodule Pleroma.Web.OAuth.Authorization do field(:token, :string) field(:valid_until, :naive_datetime) field(:used, :boolean, default: false) - belongs_to(:user, Pleroma.User) + belongs_to(:user, Pleroma.User, type: Pleroma.FlakeId) belongs_to(:app, App) timestamps() diff --git a/lib/pleroma/web/oauth/token.ex b/lib/pleroma/web/oauth/token.ex index f0ebc63f6..4e01b123b 100644 --- a/lib/pleroma/web/oauth/token.ex +++ b/lib/pleroma/web/oauth/token.ex @@ -14,7 +14,7 @@ defmodule Pleroma.Web.OAuth.Token do field(:token, :string) field(:refresh_token, :string) field(:valid_until, :naive_datetime) - belongs_to(:user, Pleroma.User) + belongs_to(:user, Pleroma.User, type: Pleroma.FlakeId) belongs_to(:app, App) timestamps() diff --git a/lib/pleroma/web/push/subscription.ex b/lib/pleroma/web/push/subscription.ex index 82b30950c..bd9d9f3a7 100644 --- a/lib/pleroma/web/push/subscription.ex +++ b/lib/pleroma/web/push/subscription.ex @@ -10,7 +10,7 @@ defmodule Pleroma.Web.Push.Subscription do alias Pleroma.Web.Push.Subscription schema "push_subscriptions" do - belongs_to(:user, User) + belongs_to(:user, User, type: Pleroma.FlakeId) belongs_to(:token, Token) field(:endpoint, :string) field(:key_p256dh, :string) diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index ede079963..43f8d64d0 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -265,8 +265,6 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end def fetch_conversation(%{assigns: %{user: user}} = conn, %{"id" => id}) do - id = String.to_integer(id) - with context when is_binary(context) <- TwitterAPI.conversation_id_to_context(id), activities <- ActivityPub.fetch_activities_for_context(context, %{ @@ -340,38 +338,42 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end def favorite(%{assigns: %{user: user}} = conn, %{"id" => id}) do - with {_, {:ok, id}} <- {:param_cast, Ecto.Type.cast(:integer, id)}, - {:ok, activity} <- TwitterAPI.fav(user, id) do + with {:ok, activity} <- TwitterAPI.fav(user, id) do conn |> put_view(ActivityView) |> render("activity.json", %{activity: activity, for: user}) + else + _ -> json_reply(conn, 400, Jason.encode!(%{})) end end def unfavorite(%{assigns: %{user: user}} = conn, %{"id" => id}) do - with {_, {:ok, id}} <- {:param_cast, Ecto.Type.cast(:integer, id)}, - {:ok, activity} <- TwitterAPI.unfav(user, id) do + with {:ok, activity} <- TwitterAPI.unfav(user, id) do conn |> put_view(ActivityView) |> render("activity.json", %{activity: activity, for: user}) + else + _ -> json_reply(conn, 400, Jason.encode!(%{})) end end def retweet(%{assigns: %{user: user}} = conn, %{"id" => id}) do - with {_, {:ok, id}} <- {:param_cast, Ecto.Type.cast(:integer, id)}, - {:ok, activity} <- TwitterAPI.repeat(user, id) do + with {:ok, activity} <- TwitterAPI.repeat(user, id) do conn |> put_view(ActivityView) |> render("activity.json", %{activity: activity, for: user}) + else + _ -> json_reply(conn, 400, Jason.encode!(%{})) end end def unretweet(%{assigns: %{user: user}} = conn, %{"id" => id}) do - with {_, {:ok, id}} <- {:param_cast, Ecto.Type.cast(:integer, id)}, - {:ok, activity} <- TwitterAPI.unrepeat(user, id) do + with {:ok, activity} <- TwitterAPI.unrepeat(user, id) do conn |> put_view(ActivityView) |> render("activity.json", %{activity: activity, for: user}) + else + _ -> json_reply(conn, 400, Jason.encode!(%{})) end end @@ -556,7 +558,6 @@ defmodule Pleroma.Web.TwitterAPI.Controller do def approve_friend_request(conn, %{"user_id" => uid} = _params) do with followed <- conn.assigns[:user], - uid when is_number(uid) <- String.to_integer(uid), %User{} = follower <- Repo.get(User, uid), {:ok, follower} <- User.maybe_follow(follower, followed), %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), @@ -578,7 +579,6 @@ defmodule Pleroma.Web.TwitterAPI.Controller do def deny_friend_request(conn, %{"user_id" => uid} = _params) do with followed <- conn.assigns[:user], - uid when is_number(uid) <- String.to_integer(uid), %User{} = follower <- Repo.get(User, uid), %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), {:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "reject"), diff --git a/lib/pleroma/web/websub/websub_client_subscription.ex b/lib/pleroma/web/websub/websub_client_subscription.ex index 105b0069f..969ee0684 100644 --- a/lib/pleroma/web/websub/websub_client_subscription.ex +++ b/lib/pleroma/web/websub/websub_client_subscription.ex @@ -13,7 +13,7 @@ defmodule Pleroma.Web.Websub.WebsubClientSubscription do field(:state, :string) field(:subscribers, {:array, :string}, default: []) field(:hub, :string) - belongs_to(:user, User) + belongs_to(:user, User, type: Pleroma.FlakeId) timestamps() end -- cgit v1.2.3 From 9d63b27dcd61dff61b77b6df0ef8a4cf8d7c87e3 Mon Sep 17 00:00:00 2001 From: href Date: Tue, 15 Jan 2019 16:18:18 +0100 Subject: Test FlakeID old id compat & Ecto type --- lib/pleroma/flake_id.ex | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/flake_id.ex b/lib/pleroma/flake_id.ex index 3c72807ca..f23c6d4b0 100644 --- a/lib/pleroma/flake_id.ex +++ b/lib/pleroma/flake_id.ex @@ -1,3 +1,7 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2018 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + defmodule Pleroma.FlakeId do @moduledoc """ Flake is a decentralized, k-ordered id generation service. @@ -38,6 +42,8 @@ defmodule Pleroma.FlakeId do def from_string(unquote(Kernel.to_string(i))), do: <<0::integer-size(128)>> end + def from_string(flake = <<_::integer-size(128)>>), do: flake + def from_string(string) when is_binary(string) and byte_size(string) < 18 do case Integer.parse(string) do {id, _} -> <<0::integer-size(64), id::integer-size(64)>> -- cgit v1.2.3 From cdc5e6ff5ca97f9123998f8af5f7b9d89b485a0c Mon Sep 17 00:00:00 2001 From: href Date: Tue, 15 Jan 2019 16:39:23 +0100 Subject: ActivityPub: restrict_since/restrict_max: ignore empty param --- lib/pleroma/web/activity_pub/activity_pub.ex | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 82fffd324..85fa83e2b 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -410,6 +410,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> Enum.reverse() end + defp restrict_since(query, %{"since_id" => ""}), do: query + defp restrict_since(query, %{"since_id" => since_id}) do from(activity in query, where: activity.id > ^since_id) end @@ -465,6 +467,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp restrict_local(query, _), do: query + defp restrict_max(query, %{"max_id" => ""}), do: query + defp restrict_max(query, %{"max_id" => max_id}) do from(activity in query, where: activity.id < ^max_id) end -- cgit v1.2.3 From 422e60ad7693ecc06f5fe6dfd65a61caf338e6b6 Mon Sep 17 00:00:00 2001 From: href Date: Tue, 15 Jan 2019 16:42:33 +0100 Subject: 2019 --- lib/pleroma/flake_id.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/flake_id.ex b/lib/pleroma/flake_id.ex index f23c6d4b0..af04fc6a4 100644 --- a/lib/pleroma/flake_id.ex +++ b/lib/pleroma/flake_id.ex @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2018 Pleroma Authors +# Copyright © 2017-2019 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.FlakeId do -- cgit v1.2.3 From e36a434b990cfdd650aed1710c55b1f62bd93ccb Mon Sep 17 00:00:00 2001 From: href Date: Wed, 16 Jan 2019 10:01:15 +0100 Subject: FlakeId.from_string/1: remove old, un-needed conversion --- lib/pleroma/flake_id.ex | 4 ---- 1 file changed, 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/flake_id.ex b/lib/pleroma/flake_id.ex index af04fc6a4..6b83ee890 100644 --- a/lib/pleroma/flake_id.ex +++ b/lib/pleroma/flake_id.ex @@ -33,10 +33,6 @@ defmodule Pleroma.FlakeId do def to_string(s), do: s - def from_string(<>) do - <<0::integer-size(64), id::integer-size(64)>> - end - for i <- [-1, 0] do def from_string(unquote(i)), do: <<0::integer-size(128)>> def from_string(unquote(Kernel.to_string(i))), do: <<0::integer-size(128)>> -- cgit v1.2.3 From 973c9eed18b2e69c6dd43eacaa040cfeabc772bc Mon Sep 17 00:00:00 2001 From: href Date: Wed, 16 Jan 2019 16:15:46 +0100 Subject: Treat User.Info pinned ids as strings --- lib/pleroma/user/info.ex | 2 +- lib/pleroma/web/twitter_api/twitter_api_controller.ex | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index fb1791c20..c6c923aac 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -31,7 +31,7 @@ defmodule Pleroma.User.Info do field(:hub, :string, default: nil) field(:salmon, :string, default: nil) field(:hide_network, :boolean, default: false) - field(:pinned_activities, {:array, :integer}, default: []) + field(:pinned_activities, {:array, :string}, default: []) # Found in the wild # ap_id -> Where is this used? diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 43f8d64d0..65ae7aabf 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -378,8 +378,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end def pin(%{assigns: %{user: user}} = conn, %{"id" => id}) do - with {_, {:ok, id}} <- {:param_cast, Ecto.Type.cast(:integer, id)}, - {:ok, activity} <- TwitterAPI.pin(user, id) do + with {:ok, activity} <- TwitterAPI.pin(user, id) do conn |> put_view(ActivityView) |> render("activity.json", %{activity: activity, for: user}) @@ -390,8 +389,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end def unpin(%{assigns: %{user: user}} = conn, %{"id" => id}) do - with {_, {:ok, id}} <- {:param_cast, Ecto.Type.cast(:integer, id)}, - {:ok, activity} <- TwitterAPI.unpin(user, id) do + with {:ok, activity} <- TwitterAPI.unpin(user, id) do conn |> put_view(ActivityView) |> render("activity.json", %{activity: activity, for: user}) -- cgit v1.2.3 From a92c43bc4be914ac9f8118cae18bc82e2b9d1664 Mon Sep 17 00:00:00 2001 From: href Date: Wed, 23 Jan 2019 11:21:52 +0100 Subject: Clippy! --- lib/pleroma/clippy.ex | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 lib/pleroma/clippy.ex (limited to 'lib') diff --git a/lib/pleroma/clippy.ex b/lib/pleroma/clippy.ex new file mode 100644 index 000000000..5e82ed8e2 --- /dev/null +++ b/lib/pleroma/clippy.ex @@ -0,0 +1,144 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Clippy do + @moduledoc false + # No software is complete until they have a Clippy implementation. + # A ballmer peak _may_ be required to change this module. + + def tip() do + tips() + |> Enum.random() + |> puts() + end + + def tips() do + host = Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host]) + + [ + "“πλήρωμα” is “pleroma” in greek", + "For an extended Pleroma Clippy Experience, use the “Redmond” themes in Pleroma FE settings", + "Staff accounts and MRF policies of Pleroma instances are disclosed on the NodeInfo endpoints for easy transparency!\n +- https://catgirl.science/misc/nodeinfo.lua?#{host} +- https://fediverse.network/#{host}/federation", + "Pleroma can federate to the Dark Web!\n +- Tor: https://git.pleroma.social/pleroma/pleroma/wikis/Easy%20Onion%20Federation%20(Tor) +- i2p: https://git.pleroma.social/pleroma/pleroma/wikis/I2p%20federation", + "Lists of Pleroma instances are available at:\n\n- http://distsn.org/pleroma-instances.html\n- https://fediverse.network/pleroma\n- https://the-federation.info/pleroma", + "Pleroma uses the LitePub protocol - https://litepub.social", + "To receive more federated posts, subscribe to relays!\n +- How-to: https://git.pleroma.social/pleroma/pleroma/wikis/Admin%20tasks#relay-managment +- Relays: https://fediverse.network/activityrelay" + ] + end + + @spec puts(String.t() | [[IO.ANSI.ansicode() | String.t(), ...], ...]) :: nil + def puts(text_or_lines) do + import IO.ANSI + + lines = + if is_binary(text_or_lines) do + String.split(text_or_lines, ~r/\n/) + else + text_or_lines + end + + longest_line_size = + lines + |> Enum.map(&charlist_count_text/1) + |> Enum.sort(&>=/2) + |> List.first() + + pad_text = longest_line_size + + pad = + for(_ <- 1..pad_text, do: "_") + |> Enum.join("") + + pad_spaces = + for(_ <- 1..pad_text, do: " ") + |> Enum.join("") + + spaces = " " + + pre_lines = [ + " / \\#{spaces} _#{pad}___", + " | |#{spaces} / #{pad_spaces} \\" + ] + + for l <- pre_lines do + IO.puts(l) + end + + clippy_lines = [ + " #{bright()}@ @#{reset()}#{spaces} ", + " || ||#{spaces}", + " || || <--", + " |\\_/| ", + " \\___/ " + ] + + noclippy_line = " " + + env = %{ + max_size: pad_text, + pad: pad, + pad_spaces: pad_spaces, + spaces: spaces, + pre_lines: pre_lines, + noclippy_line: noclippy_line + } + + clippy_line(lines, clippy_lines, env) + rescue + e -> + IO.puts("(Clippy crashed, sorry: #{inspect(e)})") + IO.puts(text_or_lines) + end + + defp clippy_line([line | lines], [prefix | clippy_lines], env) do + IO.puts([prefix <> "| ", rpad_line(line, env.max_size)]) + clippy_line(lines, clippy_lines, env) + end + + # more text lines but clippy's complete + defp clippy_line([line | lines], [], env) do + IO.puts([env.noclippy_line, "| ", rpad_line(line, env.max_size)]) + + if lines == [] do + IO.puts(env.noclippy_line <> "\\_#{env.pad}___/") + end + + clippy_line(lines, [], env) + end + + # no more text lines but clippy's not complete + defp clippy_line([], [clippy | clippy_lines], env) do + if env.pad do + IO.puts(clippy <> "\\_#{env.pad}___/") + clippy_line([], clippy_lines, %{env | pad: nil}) + else + IO.puts(clippy) + clippy_line([], clippy_lines, env) + end + end + + defp clippy_line(_, _, _) do + end + + defp rpad_line(line, max) do + pad = max - (charlist_count_text(line) - 2) + pads = Enum.join(for(_ <- 1..pad, do: " ")) + [IO.ANSI.format(line), pads <> " |"] + end + + defp charlist_count_text(line) do + if is_list(line) do + text = Enum.join(Enum.filter(line, &is_binary/1)) + String.length(text) + else + String.length(line) + end + end +end -- cgit v1.2.3 From 4333fea1dc2942526c78d97f3e8694fdc79b0575 Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Wed, 23 Jan 2019 19:47:51 +0300 Subject: Send "hide_network" in user_view --- lib/pleroma/web/twitter_api/views/user_view.ex | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex index a8cf83613..15682db8f 100644 --- a/lib/pleroma/web/twitter_api/views/user_view.ex +++ b/lib/pleroma/web/twitter_api/views/user_view.ex @@ -108,6 +108,7 @@ defmodule Pleroma.Web.TwitterAPI.UserView do "locked" => user.info.locked, "default_scope" => user.info.default_scope, "no_rich_text" => user.info.no_rich_text, + "hide_network" => user.info.hide_network, "fields" => fields, # Pleroma extension -- cgit v1.2.3 From 54ec6d09b012e90cd42c00e218df4cc7b99410a4 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 24 Jan 2019 09:35:19 +0000 Subject: mrf: add anti-followbot policy --- .../web/activity_pub/mrf/anti_followbot_policy.ex | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 lib/pleroma/web/activity_pub/mrf/anti_followbot_policy.ex (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/mrf/anti_followbot_policy.ex b/lib/pleroma/web/activity_pub/mrf/anti_followbot_policy.ex new file mode 100644 index 000000000..7c6ad582a --- /dev/null +++ b/lib/pleroma/web/activity_pub/mrf/anti_followbot_policy.ex @@ -0,0 +1,57 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.MRF.AntiFollowbotPolicy do + alias Pleroma.User + + @behaviour Pleroma.Web.ActivityPub.MRF + + # XXX: this should become User.normalize_by_ap_id() or similar, really. + defp normalize_by_ap_id(%{"id" => id}), do: User.get_cached_by_ap_id(id) + defp normalize_by_ap_id(uri) when is_binary(uri), do: User.get_cached_by_ap_id(uri) + defp normalize_by_ap_id(_), do: nil + + defp score_nickname("followbot@" <> _), do: 1.0 + defp score_nickname("federationbot@" <> _), do: 1.0 + defp score_nickname("federation_bot@" <> _), do: 1.0 + defp score_nickname(_), do: 0.0 + + defp score_displayname("federation bot"), do: 1.0 + defp score_displayname("federationbot"), do: 1.0 + defp score_displayname("fedibot"), do: 1.0 + defp score_displayname(_), do: 0.0 + + defp determine_if_followbot(%User{nickname: nickname, name: displayname}) do + nick_score = + nickname + |> String.downcase() + |> score_nickname() + + name_score = + displayname + |> String.downcase() + |> score_displayname() + + nick_score + name_score + end + + defp determine_if_followbot(_), do: 0.0 + + @impl true + def filter(%{"type" => "Follow", "actor" => actor_id} = message) do + %User{} = actor = normalize_by_ap_id(actor_id) + + score = determine_if_followbot(actor) + + # TODO: scan biography data for keywords and score it somehow. + if score < 0.8 do + {:ok, message} + else + {:reject, nil} + end + end + + @impl true + def filter(message), do: {:ok, message} +end -- cgit v1.2.3 From be43aa2875e08cd48b10fc0157d71239f098d1e4 Mon Sep 17 00:00:00 2001 From: href Date: Thu, 24 Jan 2019 13:08:27 +0100 Subject: FlakeId: ignore null mac for workerid, use first mac --- lib/pleroma/flake_id.ex | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/flake_id.ex b/lib/pleroma/flake_id.ex index 6b83ee890..26399ae05 100644 --- a/lib/pleroma/flake_id.ex +++ b/lib/pleroma/flake_id.ex @@ -161,23 +161,23 @@ defmodule Pleroma.FlakeId do 1_000_000_000 * mega_seconds + seconds * 1000 + :erlang.trunc(micro_seconds / 1000) end - defp mac do + def mac do {:ok, addresses} = :inet.getifaddrs() - ifaces_with_mac = - Enum.reduce(addresses, [], fn {iface, attrs}, acc -> - if attrs[:hwaddr], do: [iface | acc], else: acc + macids = + Enum.reduce(addresses, [], fn {_iface, attrs}, acc -> + case attrs[:hwaddr] do + [0, 0, 0 | _] -> acc + mac when is_list(mac) -> [mac_to_worker_id(mac) | acc] + _ -> acc + end end) - iface = Enum.at(ifaces_with_mac, :rand.uniform(length(ifaces_with_mac)) - 1) - mac(iface) + List.first(macids) end - defp mac(name) do - {:ok, addresses} = :inet.getifaddrs() - proplist = :proplists.get_value(name, addresses) - hwaddr = Enum.take(:proplists.get_value(:hwaddr, proplist), 6) - <> = :binary.list_to_bin(hwaddr) + def mac_to_worker_id(mac) do + <> = :binary.list_to_bin(mac) worker end end -- cgit v1.2.3 From a3ba72d97849ba12a5ea4008bd0b97e80bdd588b Mon Sep 17 00:00:00 2001 From: href Date: Thu, 24 Jan 2019 16:15:13 +0100 Subject: Fix clippy with one/five lines --- lib/pleroma/clippy.ex | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/clippy.ex b/lib/pleroma/clippy.ex index 5e82ed8e2..4e9bdbe19 100644 --- a/lib/pleroma/clippy.ex +++ b/lib/pleroma/clippy.ex @@ -25,7 +25,7 @@ defmodule Pleroma.Clippy do "Pleroma can federate to the Dark Web!\n - Tor: https://git.pleroma.social/pleroma/pleroma/wikis/Easy%20Onion%20Federation%20(Tor) - i2p: https://git.pleroma.social/pleroma/pleroma/wikis/I2p%20federation", - "Lists of Pleroma instances are available at:\n\n- http://distsn.org/pleroma-instances.html\n- https://fediverse.network/pleroma\n- https://the-federation.info/pleroma", + "Lists of Pleroma instances:\n\n- http://distsn.org/pleroma-instances.html\n- https://fediverse.network/pleroma\n- https://the-federation.info/pleroma", "Pleroma uses the LitePub protocol - https://litepub.social", "To receive more federated posts, subscribe to relays!\n - How-to: https://git.pleroma.social/pleroma/pleroma/wikis/Admin%20tasks#relay-managment @@ -90,6 +90,17 @@ defmodule Pleroma.Clippy do noclippy_line: noclippy_line } + # surrond one/five line clippy with blank lines around to not fuck up the layout + # + # yes this fix sucks but it's good enough, have you ever seen a release of windows wihtout some butched + # features anyway? + lines = + if length(lines) == 1 or length(lines) == 5 do + [""] ++ lines ++ [""] + else + lines + end + clippy_line(lines, clippy_lines, env) rescue e -> -- cgit v1.2.3