aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/notification.ex26
-rw-r--r--lib/pleroma/user.ex39
-rw-r--r--lib/pleroma/user/info.ex27
3 files changed, 91 insertions, 1 deletions
diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex
index b357d5399..d79f0f563 100644
--- a/lib/pleroma/notification.ex
+++ b/lib/pleroma/notification.ex
@@ -17,6 +17,8 @@ defmodule Pleroma.Notification do
import Ecto.Query
import Ecto.Changeset
+ @type t :: %__MODULE__{}
+
schema "notifications" do
field(:seen, :boolean, default: false)
belongs_to(:user, User, type: Pleroma.FlakeId)
@@ -51,6 +53,25 @@ defmodule Pleroma.Notification do
|> Pagination.fetch_paginated(opts)
end
+ @doc """
+ Returns notifications for user received since given date.
+
+ ## Examples
+
+ iex> Pleroma.Notification.for_user_since(%Pleroma.User{}, ~N[2019-04-13 11:22:33])
+ [%Pleroma.Notification{}, %Pleroma.Notification{}]
+
+ iex> Pleroma.Notification.for_user_since(%Pleroma.User{}, ~N[2019-04-15 11:22:33])
+ []
+ """
+ @spec for_user_since(Pleroma.User.t(), NaiveDateTime.t()) :: [t()]
+ def for_user_since(user, date) do
+ from(n in for_user_query(user),
+ where: n.updated_at > ^date
+ )
+ |> Repo.all()
+ end
+
def set_read_up_to(%{id: user_id} = _user, id) do
query =
from(
@@ -58,7 +79,10 @@ defmodule Pleroma.Notification do
where: n.user_id == ^user_id,
where: n.id <= ^id,
update: [
- set: [seen: true]
+ set: [
+ seen: true,
+ updated_at: ^NaiveDateTime.utc_now()
+ ]
]
)
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 78eb29ddd..7053dfaf3 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -55,6 +55,7 @@ defmodule Pleroma.User do
field(:tags, {:array, :string}, default: [])
field(:bookmarks, {:array, :string}, default: [])
field(:last_refreshed_at, :naive_datetime_usec)
+ field(:last_digest_emailed_at, :naive_datetime)
has_many(:notifications, Notification)
has_many(:registrations, Registration)
embeds_one(:info, Pleroma.User.Info)
@@ -1445,4 +1446,42 @@ defmodule Pleroma.User do
def showing_reblogs?(%User{} = user, %User{} = target) do
target.ap_id not in user.info.muted_reblogs
end
+
+ @doc """
+ The function returns a query to get users with no activity for given interval of days.
+ Inactive users are those who didn't read any notification, or had any activity where
+ the user is the activity's actor, during `inactivity_threshold` days.
+ Deactivated users will not appear in this list.
+
+ ## Examples
+
+ iex> Pleroma.User.list_inactive_users()
+ %Ecto.Query{}
+ """
+ @spec list_inactive_users_query(integer()) :: Ecto.Query.t()
+ def list_inactive_users_query(inactivity_threshold \\ 7) do
+ negative_inactivity_threshold = -inactivity_threshold
+ now = NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second)
+ # Subqueries are not supported in `where` clauses, join gets too complicated.
+ has_read_notifications =
+ from(n in Pleroma.Notification,
+ where: n.seen == true,
+ group_by: n.id,
+ having: max(n.updated_at) > datetime_add(^now, ^negative_inactivity_threshold, "day"),
+ select: n.user_id
+ )
+ |> Pleroma.Repo.all()
+
+ from(u in Pleroma.User,
+ left_join: a in Pleroma.Activity,
+ on: u.ap_id == a.actor,
+ where: not is_nil(u.nickname),
+ where: fragment("not (?->'deactivated' @> 'true')", u.info),
+ where: u.id not in ^has_read_notifications,
+ group_by: u.id,
+ having:
+ max(a.inserted_at) < datetime_add(^now, ^negative_inactivity_threshold, "day") or
+ is_nil(max(a.inserted_at))
+ )
+ end
end
diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex
index 5afa7988c..194dd5581 100644
--- a/lib/pleroma/user/info.ex
+++ b/lib/pleroma/user/info.ex
@@ -8,6 +8,8 @@ defmodule Pleroma.User.Info do
alias Pleroma.User.Info
+ @type t :: %__MODULE__{}
+
embedded_schema do
field(:banner, :map, default: %{})
field(:background, :map, default: %{})
@@ -40,6 +42,7 @@ defmodule Pleroma.User.Info do
field(:hide_follows, :boolean, default: false)
field(:pinned_activities, {:array, :string}, default: [])
field(:flavour, :string, default: nil)
+ field(:email_notifications, :map, default: %{"digest" => true})
field(:notification_settings, :map,
default: %{"remote" => true, "local" => true, "followers" => true, "follows" => true}
@@ -75,6 +78,30 @@ defmodule Pleroma.User.Info do
|> validate_required([:notification_settings])
end
+ @doc """
+ Update email notifications in the given User.Info struct.
+
+ Examples:
+
+ iex> update_email_notifications(%Pleroma.User.Info{email_notifications: %{"digest" => false}}, %{"digest" => true})
+ %Pleroma.User.Info{email_notifications: %{"digest" => true}}
+
+ """
+ @spec update_email_notifications(t(), map()) :: Ecto.Changeset.t()
+ def update_email_notifications(info, settings) do
+ email_notifications =
+ info.email_notifications
+ |> Map.merge(settings)
+ |> Map.take(["digest"])
+
+ params = %{email_notifications: email_notifications}
+ fields = [:email_notifications]
+
+ info
+ |> cast(params, fields)
+ |> validate_required(fields)
+ end
+
def add_to_note_count(info, number) do
set_note_count(info, info.note_count + number)
end