Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Purge inactive friends and avoids #541

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions lib/teiserver/account/libs/relationship_lib.ex
Original file line number Diff line number Diff line change
Expand Up @@ -388,4 +388,25 @@ defmodule Teiserver.Account.RelationshipLib do

results.rows
end

# Deletes inactive users in the ignore/avoid/block list of a user
# Returns the number of deletions
def delete_inactive_ignores_avoids_blocks(user_id, days_not_logged_in) do
query = """
delete from account_relationships ar
using account_users au
where au.id = ar.to_user_id
and ar.from_user_id = $1
and (au.last_login is null OR
abs(DATE_PART('day', (now()- au.last_login ))) > $2);
"""

results =
Ecto.Adapters.SQL.query!(Repo, query, [
user_id,
days_not_logged_in
])

results.num_rows
jauggy marked this conversation as resolved.
Show resolved Hide resolved
end
end
79 changes: 79 additions & 0 deletions lib/teiserver_web/live/account/relationship/index.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
defmodule TeiserverWeb.Account.RelationshipLive.Index do
@moduledoc false
alias Teiserver.Account.FriendLib
alias Teiserver.Account.RelationshipLib
use TeiserverWeb, :live_view
alias Teiserver.Account

Expand All @@ -12,6 +14,8 @@ defmodule TeiserverWeb.Account.RelationshipLive.Index do
|> assign(:view_colour, Account.RelationshipLib.colour())
|> assign(:show_help, false)
|> put_empty_relationships
|> assign(:purge_cutoff, "6 months")
|> assign(:purge_cutoff_options, ["1 month", "3 months", "6 months", "1 year"])

{:ok, socket}
end
Expand Down Expand Up @@ -54,6 +58,12 @@ defmodule TeiserverWeb.Account.RelationshipLive.Index do
|> update_user_search
end

defp apply_action(socket, :clean, _params) do
socket
|> assign(:page_title, "Relationships - Cleanup")
|> assign(:tab, :clean)
end

@impl true
def handle_event("show-help", _, socket) do
{:noreply, socket |> assign(:show_help, true)}
Expand Down Expand Up @@ -255,6 +265,58 @@ defmodule TeiserverWeb.Account.RelationshipLive.Index do
{:noreply, socket}
end

def handle_event("purge-avoids", _params, socket) do
userid = socket.assigns.current_user.id
days = get_purge_days_cutoff(socket)
num_rows = RelationshipLib.delete_inactive_ignores_avoids_blocks(userid, days)

socket =
socket |> assign(:purge_avoids_message, "#{num_rows} inactive users purged.")

{:noreply, socket}
end

def handle_event("purge-friends", _params, socket) do
days_cutoff = get_purge_days_cutoff(socket)

# Get all friends of this user
friends = socket.assigns[:friends]

num_friends_deleted =
Enum.map(friends, fn friend ->
last_login = friend.other_user.last_login
days = abs(DateTime.diff(last_login, Timex.now(), :day))
should_delete? = days > days_cutoff

if(should_delete?) do
# Delete friend
Account.delete_friend(friend)
end

should_delete?
end)
|> Enum.filter(fn deleted? -> deleted? == true end)
|> length()

socket =
socket |> assign(:purge_friends_message, "#{num_friends_deleted} inactive friends purged.")
jauggy marked this conversation as resolved.
Show resolved Hide resolved

{:noreply, socket}
end

@doc """
Handles the dropdown for purge cutoff time
"""
@impl true
def handle_event("update-purge-cutoff", event, socket) do
[key] = event["_target"]
value = event[key]

{:noreply,
socket
|> assign(:purge_cutoff, value)}
end

defp update_user_search(
%{assigns: %{live_action: :search, search_terms: terms} = assigns} = socket
) do
Expand Down Expand Up @@ -413,4 +475,21 @@ defmodule TeiserverWeb.Account.RelationshipLive.Index do
|> assign(:ignores, ignores)
|> assign(:blocks, blocks)
end

def get_purge_days_cutoff(socket) do
jauggy marked this conversation as resolved.
Show resolved Hide resolved
duration = socket.assigns[:purge_cutoff]
[_, number, type] = Regex.run(~r/(\d) (month|year)/, duration)
jauggy marked this conversation as resolved.
Show resolved Hide resolved
{number, _} = Integer.parse(number)

cond do
type == "year" ->
number * 365

type == "month" ->
number * 365.0 / 12

true ->
raise("Incorrect value assigned to :purge_cutoff")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put the incorrect value in the message, when debugging it's really useful.
Also, what happen if you pass an incorrect value? Does the user see a nasty server error?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error should be received by the dev. The user can only choose options so would never get an error unless a future dev added an option that didn't work. So I probably need to make a test function to make sure a future dev doesn't input an option that would break.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this is not really a dev here, because this value is coming from a user. Sure, using the web page as intended will not give you weird values but anyone could submit whatever they want.

Copy link
Member Author

@jauggy jauggy Dec 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How could a user submit a value other than the options I have given them? All they have access to is a dropdown. The options available are hardcoded and set by the developer.

end
end
end
54 changes: 54 additions & 0 deletions lib/teiserver_web/live/account/relationship/index.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
<.tab_nav url={~p"/account/relationship/search"} selected={@tab == :search}>
<Fontawesome.icon icon="search" style="solid" /> Search users
</.tab_nav>
<.tab_nav url={~p"/account/relationship/clean"} selected={@tab == :clean}>
<Fontawesome.icon icon="broom" style="solid" /> Cleanup
</.tab_nav>
</.tab_header>
</div>
</div>
Expand Down Expand Up @@ -412,3 +415,54 @@
</div>
</div>
</div>

<div :if={@live_action == :clean} class="row mt-2 mb-3">
<div class="col-xl-6">
<h4 class="text-danger">
Avoid Cleanup
</h4>

<form method="post" class="col-md-6 ">
<span>
Purge users from your ignore, avoid, and block list that have not logged in for:
</span>
<.input
type="select"
options={@purge_cutoff_options}
name="algorithm"
value={@purge_cutoff}
phx-change="update-purge-cutoff"
/>
<div class="btn btn-danger btn-sm col-sm-12 mt-2" phx-click="purge-avoids">
Purge inactive ignores / avoids / blocks
</div>
<%= if(assigns[:purge_avoids_message]) do %>
<p class="mt-2"><%= @purge_avoids_message %></p>
<% end %>
</form>
<br />
<br />
<br />
<h4 class="text-success">
Friend Cleanup
</h4>
<form method="post" class="col-md-6">
<span>
Purge users from your friend list that have not logged in for:
</span>
<.input
type="select"
options={@purge_cutoff_options}
name="algorithm"
value={@purge_cutoff}
phx-change="update-purge-cutoff"
/>
<div class="btn btn-success btn-sm col-sm-12 mt-2" phx-click="purge-friends">
Purge inactive Friends
</div>
<%= if(assigns[:purge_friends_message]) do %>
<p class="mt-2"><%= @purge_friends_message %></p>
<% end %>
jauggy marked this conversation as resolved.
Show resolved Hide resolved
</form>
</div>
</div>
1 change: 1 addition & 0 deletions lib/teiserver_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ defmodule TeiserverWeb.Router do
live "/relationship/follow", RelationshipLive.Index, :follow
live "/relationship/avoid", RelationshipLive.Index, :avoid
live "/relationship/search", RelationshipLive.Index, :search
live "/relationship/clean", RelationshipLive.Index, :clean
end

live_session :account_settings,
Expand Down
Loading