diff options
author | Ivan Tashkinov <ivantashkinov@gmail.com> | 2019-10-23 17:22:42 +0300 |
---|---|---|
committer | Ivan Tashkinov <ivantashkinov@gmail.com> | 2019-10-23 17:22:42 +0300 |
commit | 8cc809e44e3a899f93061c4c5f68d9736d79d79e (patch) | |
tree | 8193991e2a2b705a60d847a626d22abaf756d7f1 /lib | |
parent | 11cd9944258bfc2123b821b21321e12097d0f19b (diff) | |
parent | 54077677eaad44ea355c7f0db7ea5e94183d5a30 (diff) | |
download | pleroma-8cc809e44e3a899f93061c4c5f68d9736d79d79e.tar.gz |
Merge remote-tracking branch 'remotes/upstream/develop' into 1304-user-info-deprecation
# Conflicts:
# lib/pleroma/notification.ex
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/marker.ex | 74 | ||||
-rw-r--r-- | lib/pleroma/notification.ex | 15 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/utils.ex | 42 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/visibility.ex | 3 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/controllers/marker_controller.ex | 32 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/marker_view.ex | 17 | ||||
-rw-r--r-- | lib/pleroma/web/push/impl.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 3 |
8 files changed, 164 insertions, 26 deletions
diff --git a/lib/pleroma/marker.ex b/lib/pleroma/marker.ex new file mode 100644 index 000000000..7f87c86c3 --- /dev/null +++ b/lib/pleroma/marker.ex @@ -0,0 +1,74 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Marker do + use Ecto.Schema + + import Ecto.Changeset + import Ecto.Query + + alias Ecto.Multi + alias Pleroma.Repo + alias Pleroma.User + + @timelines ["notifications"] + + schema "markers" do + field(:last_read_id, :string, default: "") + field(:timeline, :string, default: "") + field(:lock_version, :integer, default: 0) + + belongs_to(:user, User, type: FlakeId.Ecto.CompatType) + timestamps() + end + + def get_markers(user, timelines \\ []) do + Repo.all(get_query(user, timelines)) + end + + def upsert(%User{} = user, attrs) do + attrs + |> Map.take(@timelines) + |> Enum.reduce(Multi.new(), fn {timeline, timeline_attrs}, multi -> + marker = + user + |> get_marker(timeline) + |> changeset(timeline_attrs) + + Multi.insert(multi, timeline, marker, + returning: true, + on_conflict: {:replace, [:last_read_id]}, + conflict_target: [:user_id, :timeline] + ) + end) + |> Repo.transaction() + end + + defp get_marker(user, timeline) do + case Repo.find_resource(get_query(user, timeline)) do + {:ok, marker} -> %__MODULE__{marker | user: user} + _ -> %__MODULE__{timeline: timeline, user_id: user.id} + end + end + + @doc false + defp changeset(marker, attrs) do + marker + |> cast(attrs, [:last_read_id]) + |> validate_required([:user_id, :timeline, :last_read_id]) + |> validate_inclusion(:timeline, @timelines) + end + + defp by_timeline(query, timeline) do + from(m in query, where: m.timeline in ^List.wrap(timeline)) + end + + defp by_user_id(query, id), do: from(m in query, where: m.user_id == ^id) + + defp get_query(user, timelines) do + __MODULE__ + |> by_user_id(user.id) + |> by_timeline(timelines) + end +end diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index 21b26a53d..83844d3be 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -55,9 +55,19 @@ defmodule Pleroma.Notification do ) |> preload([n, a, o], activity: {a, object: o}) |> exclude_muted(user, opts) + |> exclude_blocked(user) |> exclude_visibility(opts) end + defp exclude_blocked(query, user) do + query + |> where([n, a], a.actor not in ^user.info.blocks) + |> where( + [n, a], + fragment("substring(? from '.*://([^/]*)')", a.actor) not in ^user.info.domain_blocks + ) + end + defp exclude_muted(query, _, %{with_muted: true}) do query end @@ -65,11 +75,6 @@ defmodule Pleroma.Notification do defp exclude_muted(query, user, _opts) do query |> where([n, a], a.actor not in ^user.muted_notifications) - |> where([n, a], a.actor not in ^user.blocks) - |> where( - [n, a], - fragment("substring(? from '.*://([^/]*)')", a.actor) not in ^user.domain_blocks - ) |> join(:left, [n, a], tm in Pleroma.ThreadMute, on: tm.user_id == ^user.id and tm.context == fragment("?->>'context'", a.data) ) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 6b28df92c..699d5162f 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -49,26 +49,28 @@ defmodule Pleroma.Web.ActivityPub.Utils do def determine_explicit_mentions(_), do: [] - @spec recipient_in_collection(any(), any()) :: boolean() - 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 + @spec label_in_collection?(any(), any()) :: boolean() + defp label_in_collection?(ap_id, coll) when is_binary(coll), do: ap_id == coll + defp label_in_collection?(ap_id, coll) when is_list(coll), do: ap_id in coll + defp label_in_collection?(_, _), do: false + + @spec label_in_message?(String.t(), map()) :: boolean() + def label_in_message?(label, params), + do: + [params["to"], params["cc"], params["bto"], params["bcc"]] + |> Enum.any?(&label_in_collection?(label, &1)) + + @spec unaddressed_message?(map()) :: boolean() + def unaddressed_message?(params), + do: + [params["to"], params["cc"], params["bto"], params["bcc"]] + |> Enum.all?(&is_nil(&1)) @spec recipient_in_message(User.t(), User.t(), map()) :: boolean() - def recipient_in_message(%User{ap_id: ap_id} = recipient, %User{} = actor, params) do - addresses = [params["to"], params["cc"], params["bto"], params["bcc"]] - - cond do - Enum.any?(addresses, &recipient_in_collection(ap_id, &1)) -> true - # if the message is unaddressed at all, then assume it is directly addressed - # to the recipient - Enum.all?(addresses, &is_nil(&1)) -> true - # if the message is sent from somebody the user is following, then assume it - # is addressed to the recipient - User.following?(recipient, actor) -> true - true -> false - end - end + def recipient_in_message(%User{ap_id: ap_id} = recipient, %User{} = actor, params), + do: + label_in_message?(ap_id, params) || unaddressed_message?(params) || + User.following?(recipient, actor) defp extract_list(target) when is_binary(target), do: [target] defp extract_list(lst) when is_list(lst), do: lst @@ -76,8 +78,8 @@ defmodule Pleroma.Web.ActivityPub.Utils do def maybe_splice_recipient(ap_id, params) do need_splice? = - !recipient_in_collection(ap_id, params["to"]) && - !recipient_in_collection(ap_id, params["cc"]) + !label_in_collection?(ap_id, params["to"]) && + !label_in_collection?(ap_id, params["cc"]) if need_splice? do cc_list = extract_list(params["cc"]) diff --git a/lib/pleroma/web/activity_pub/visibility.ex b/lib/pleroma/web/activity_pub/visibility.ex index 270d0fa02..f3ab48f7c 100644 --- a/lib/pleroma/web/activity_pub/visibility.ex +++ b/lib/pleroma/web/activity_pub/visibility.ex @@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.Visibility do alias Pleroma.Object alias Pleroma.Repo alias Pleroma.User + alias Pleroma.Web.ActivityPub.Utils require Pleroma.Constants @@ -15,7 +16,7 @@ defmodule Pleroma.Web.ActivityPub.Visibility do 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: Pleroma.Constants.as_public() in (data["to"] ++ (data["cc"] || [])) + def is_public?(data), do: Utils.label_in_message?(Pleroma.Constants.as_public(), data) def is_private?(activity) do with false <- is_public?(activity), diff --git a/lib/pleroma/web/mastodon_api/controllers/marker_controller.ex b/lib/pleroma/web/mastodon_api/controllers/marker_controller.ex new file mode 100644 index 000000000..ce025624d --- /dev/null +++ b/lib/pleroma/web/mastodon_api/controllers/marker_controller.ex @@ -0,0 +1,32 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.MastodonAPI.MarkerController do + use Pleroma.Web, :controller + alias Pleroma.Plugs.OAuthScopesPlug + + plug( + OAuthScopesPlug, + %{scopes: ["read:statuses"]} + when action == :index + ) + + plug(OAuthScopesPlug, %{scopes: ["write:statuses"]} when action == :upsert) + plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug) + action_fallback(Pleroma.Web.MastodonAPI.FallbackController) + + # GET /api/v1/markers + def index(%{assigns: %{user: user}} = conn, params) do + markers = Pleroma.Marker.get_markers(user, params["timeline"]) + render(conn, "markers.json", %{markers: markers}) + end + + # POST /api/v1/markers + def upsert(%{assigns: %{user: user}} = conn, params) do + with {:ok, result} <- Pleroma.Marker.upsert(user, params), + markers <- Map.values(result) do + render(conn, "markers.json", %{markers: markers}) + end + end +end diff --git a/lib/pleroma/web/mastodon_api/views/marker_view.ex b/lib/pleroma/web/mastodon_api/views/marker_view.ex new file mode 100644 index 000000000..38fbeed5f --- /dev/null +++ b/lib/pleroma/web/mastodon_api/views/marker_view.ex @@ -0,0 +1,17 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.MastodonAPI.MarkerView do + use Pleroma.Web, :view + + def render("markers.json", %{markers: markers}) do + Enum.reduce(markers, %{}, fn m, acc -> + Map.put_new(acc, m.timeline, %{ + last_read_id: m.last_read_id, + version: m.lock_version, + updated_at: NaiveDateTime.to_iso8601(m.updated_at) + }) + end) + end +end diff --git a/lib/pleroma/web/push/impl.ex b/lib/pleroma/web/push/impl.ex index 35d3ff07c..dd445e8bf 100644 --- a/lib/pleroma/web/push/impl.ex +++ b/lib/pleroma/web/push/impl.ex @@ -125,6 +125,10 @@ defmodule Pleroma.Web.Push.Impl do end end + def format_title(%{activity: %{data: %{"directMessage" => true}}}) do + "New Direct Message" + end + def format_title(%{activity: %{data: %{"type" => type}}}) do case type do "Create" -> "New Mention" diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index f2588f89e..f69c5c2bc 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -405,6 +405,9 @@ defmodule Pleroma.Web.Router do get("/push/subscription", SubscriptionController, :get) put("/push/subscription", SubscriptionController, :update) delete("/push/subscription", SubscriptionController, :delete) + + get("/markers", MarkerController, :index) + post("/markers", MarkerController, :upsert) end scope "/api/web", Pleroma.Web do |