diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/pleroma/notification.ex | 26 | ||||
| -rw-r--r-- | lib/pleroma/user.ex | 39 | ||||
| -rw-r--r-- | lib/pleroma/user/info.ex | 27 | 
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 | 
