diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/flake_id.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/html.ex | 14 | ||||
-rw-r--r-- | lib/pleroma/notification.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/plugs/oauth_plug.ex | 7 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub.ex | 33 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 49 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/account_view.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/web/rich_media/parser.ex | 12 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 2 |
9 files changed, 119 insertions, 12 deletions
diff --git a/lib/pleroma/flake_id.ex b/lib/pleroma/flake_id.ex index 3623ac597..69ab8ccf9 100644 --- a/lib/pleroma/flake_id.ex +++ b/lib/pleroma/flake_id.ex @@ -33,6 +33,10 @@ defmodule Pleroma.FlakeId do def to_string(s), do: s + def from_string(int) when is_integer(int) do + from_string(Kernel.to_string(int)) + 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)>> diff --git a/lib/pleroma/html.ex b/lib/pleroma/html.ex index f5c6e5033..fb602d6b6 100644 --- a/lib/pleroma/html.ex +++ b/lib/pleroma/html.ex @@ -58,6 +58,20 @@ defmodule Pleroma.HTML do "#{signature}#{to_string(scrubber)}" end) end + + def extract_first_external_url(object, content) do + key = "URL|#{object.id}" + + Cachex.fetch!(:scrubber_cache, key, fn _key -> + result = + content + |> Floki.filter_out("a.mention") + |> Floki.attribute("a", "href") + |> Enum.at(0) + + {:commit, result} + end) + end end defmodule Pleroma.HTML.Scrubber.TwitterText do diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index e47145601..2364d36da 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -35,7 +35,8 @@ defmodule Pleroma.Notification do n in Notification, where: n.user_id == ^user.id, order_by: [desc: n.id], - preload: [:activity], + join: activity in assoc(n, :activity), + preload: [activity: activity], limit: 20 ) @@ -66,7 +67,8 @@ defmodule Pleroma.Notification do from( n in Notification, where: n.id == ^id, - preload: [:activity] + join: activity in assoc(n, :activity), + preload: [activity: activity] ) notification = Repo.one(query) diff --git a/lib/pleroma/plugs/oauth_plug.ex b/lib/pleroma/plugs/oauth_plug.ex index 437aa95b3..945a1d49f 100644 --- a/lib/pleroma/plugs/oauth_plug.ex +++ b/lib/pleroma/plugs/oauth_plug.ex @@ -33,7 +33,12 @@ defmodule Pleroma.Plugs.OAuthPlug do # @spec fetch_user_and_token(String.t()) :: {:ok, User.t(), Token.t()} | nil defp fetch_user_and_token(token) do - query = from(q in Token, where: q.token == ^token, preload: [:user]) + query = + from(t in Token, + where: t.token == ^token, + join: user in assoc(t, :user), + preload: [user: user] + ) with %Token{user: %{info: %{deactivated: false} = _} = user} = token_record <- Repo.one(query) do {:ok, user, token_record} diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 6b4682e35..feff22400 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -64,7 +64,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end end - defp check_remote_limit(%{"object" => %{"content" => content}}) do + defp check_remote_limit(%{"object" => %{"content" => content}}) when not is_nil(content) do limit = Pleroma.Config.get([:instance, :remote_limit]) String.length(content) <= limit end @@ -426,7 +426,34 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp restrict_since(query, _), do: query - defp restrict_tag(query, %{"tag" => tag}) do + defp restrict_tag_reject(query, %{"tag_reject" => tag_reject}) + when is_list(tag_reject) and tag_reject != [] do + from( + activity in query, + where: fragment("(not (? #> '{\"object\",\"tag\"}') \\?| ?)", activity.data, ^tag_reject) + ) + end + + defp restrict_tag_reject(query, _), do: query + + defp restrict_tag_all(query, %{"tag_all" => tag_all}) + when is_list(tag_all) and tag_all != [] do + from( + activity in query, + where: fragment("(? #> '{\"object\",\"tag\"}') \\?& ?", activity.data, ^tag_all) + ) + end + + defp restrict_tag_all(query, _), do: query + + defp restrict_tag(query, %{"tag" => tag}) when is_list(tag) do + from( + activity in query, + where: fragment("(? #> '{\"object\",\"tag\"}') \\?| ?", activity.data, ^tag) + ) + end + + defp restrict_tag(query, %{"tag" => tag}) when is_binary(tag) do from( activity in query, where: fragment("? <@ (? #> '{\"object\",\"tag\"}')", ^tag, activity.data) @@ -575,6 +602,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do base_query |> restrict_recipients(recipients, opts["user"]) |> restrict_tag(opts) + |> restrict_tag_reject(opts) + |> restrict_tag_all(opts) |> restrict_since(opts) |> restrict_local(opts) |> restrict_limit(opts) diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index f4736fcb5..a366a149f 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -6,6 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do use Pleroma.Web, :controller alias Pleroma.{Repo, Object, Activity, User, Notification, Stats} alias Pleroma.Web + alias Pleroma.HTML alias Pleroma.Web.MastodonAPI.{ StatusView, @@ -540,15 +541,34 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def hashtag_timeline(%{assigns: %{user: user}} = conn, params) do local_only = params["local"] in [true, "True", "true", "1"] - params = + tags = + [params["tag"], params["any"]] + |> List.flatten() + |> Enum.uniq() + |> Enum.filter(& &1) + |> Enum.map(&String.downcase(&1)) + + tag_all = + params["all"] || + [] + |> Enum.map(&String.downcase(&1)) + + tag_reject = + params["none"] || + [] + |> Enum.map(&String.downcase(&1)) + + query_params = params |> Map.put("type", "Create") |> Map.put("local_only", local_only) |> Map.put("blocking_user", user) - |> Map.put("tag", String.downcase(params["tag"])) + |> Map.put("tag", tags) + |> Map.put("tag_all", tag_all) + |> Map.put("tag_reject", tag_reject) activities = - ActivityPub.fetch_public_activities(params) + ActivityPub.fetch_public_activities(query_params) |> Enum.reverse() conn @@ -1322,6 +1342,29 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end + def get_status_card(status_id) do + with %Activity{} = activity <- Repo.get(Activity, status_id), + true <- ActivityPub.is_public?(activity), + %Object{} = object <- Object.normalize(activity.data["object"]), + page_url <- HTML.extract_first_external_url(object, object.data["content"]), + {:ok, rich_media} <- Pleroma.Web.RichMedia.Parser.parse(page_url) do + page_url = rich_media[:url] || page_url + site_name = rich_media[:site_name] || URI.parse(page_url).host + + rich_media + |> Map.take([:image, :title, :description]) + |> Map.put(:type, "link") + |> Map.put(:provider_name, site_name) + |> Map.put(:url, page_url) + else + _ -> %{} + end + end + + def status_card(conn, %{"id" => status_id}) do + json(conn, get_status_card(status_id)) + end + def try_render(conn, target, params) when is_binary(target) do res = render(conn, target, params) diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index bfd6b8b22..0ba4289da 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -112,7 +112,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do # Pleroma extension pleroma: %{ confirmation_pending: user_info.confirmation_pending, - tags: user.tags + tags: user.tags, + is_moderator: user.info.is_moderator, + is_admin: user.info.is_admin } } end diff --git a/lib/pleroma/web/rich_media/parser.ex b/lib/pleroma/web/rich_media/parser.ex index 6da83c6e4..947dc0c3c 100644 --- a/lib/pleroma/web/rich_media/parser.ex +++ b/lib/pleroma/web/rich_media/parser.ex @@ -5,11 +5,19 @@ defmodule Pleroma.Web.RichMedia.Parser do Pleroma.Web.RichMedia.Parsers.OEmbed ] + def parse(nil), do: {:error, "No URL provided"} + if Mix.env() == :test do def parse(url), do: parse_url(url) else - def parse(url), - do: Cachex.fetch!(:rich_media_cache, url, fn _ -> parse_url(url) end) + def parse(url) do + with {:ok, data} <- Cachex.fetch(:rich_media_cache, url, fn _ -> parse_url(url) end) do + data + else + _e -> + {:error, "Parsing error"} + end + end end defp parse_url(url) do diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index b83790858..e749aa834 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -258,7 +258,7 @@ defmodule Pleroma.Web.Router do get("/statuses/:id", MastodonAPIController, :get_status) get("/statuses/:id/context", MastodonAPIController, :get_context) - get("/statuses/:id/card", MastodonAPIController, :empty_object) + get("/statuses/:id/card", MastodonAPIController, :status_card) get("/statuses/:id/favourited_by", MastodonAPIController, :favourited_by) get("/statuses/:id/reblogged_by", MastodonAPIController, :reblogged_by) |