-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
206 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
defmodule MiataBot.NewUsersTimer do | ||
use Ecto.Schema | ||
import Ecto.Changeset | ||
|
||
@enactment_date %DateTime{ | ||
calendar: Calendar.ISO, | ||
day: 22, | ||
hour: 12, | ||
microsecond: {0, 0}, | ||
minute: 0, | ||
month: 12, | ||
second: 0, | ||
std_offset: 0, | ||
time_zone: "Etc/UTC", | ||
utc_offset: 0, | ||
year: 2023, | ||
zone_abbr: "UTC" | ||
} | ||
|
||
schema "new_users" do | ||
field(:joined_at, :utc_datetime) | ||
field(:refreshed_at, :utc_datetime, default: @enactment_date) | ||
field(:discord_user_id, Snowflake) | ||
field(:discord_guild_id, Snowflake) | ||
end | ||
|
||
def changeset(new_user, params \\ %{}) do | ||
new_user | ||
|> cast(params, [ | ||
:joined_at, | ||
:refreshed_at, | ||
:discord_user_id, | ||
:discord_guild_id | ||
]) | ||
|> unique_constraint([:discord_guild_id, :discord_user_id]) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
defmodule MiataBotDiscord.NewUsersListener do | ||
require Logger | ||
|
||
use Quarrel.Listener | ||
alias MiataBot.{Repo, NewUsersTimer} | ||
import Ecto.Query | ||
@expiry_days 0 | ||
|
||
def debug_expire_timer(timer, refreshed_at \\ nil) do | ||
refreshed_at = | ||
refreshed_at || | ||
%DateTime{ | ||
calendar: Calendar.ISO, | ||
day: 20, | ||
hour: 19, | ||
microsecond: {0, 0}, | ||
minute: 41, | ||
month: 6, | ||
second: 27, | ||
std_offset: 0, | ||
time_zone: "Etc/UTC", | ||
utc_offset: 0, | ||
year: 2019, | ||
zone_abbr: "UTC" | ||
} | ||
|
||
NewUsersTimer.changeset(timer, %{refreshed_at: refreshed_at}) | ||
|> Repo.update!() | ||
end | ||
|
||
@impl GenServer | ||
def init(state) do | ||
send(self(), :checkup) | ||
{:ok, state} | ||
end | ||
|
||
@impl GenServer | ||
def handle_info(:checkup, state) do | ||
guild_id = state.guild.id | ||
timers = Repo.all(from t in NewUsersTimer, where: t.discord_guild_id == ^guild_id) | ||
{:noreply, state, {:continue, timers}} | ||
end | ||
|
||
@impl GenServer | ||
def handle_continue([timer | rest], state) do | ||
begin = timer.refreshed_at || timer.joined_at | ||
complete = Timex.shift(begin, days: @expiry_days) | ||
now = DateTime.utc_now() | ||
|
||
case Timex.compare(now, complete, :days) do | ||
-1 -> | ||
# now comes before compelte | ||
# timer is not up yet | ||
:ok | ||
|
||
0 -> | ||
# now is the same day as complete | ||
# timer is expired | ||
do_expire_timer(timer, state) | ||
|
||
1 -> | ||
# now is after complete | ||
# timer is expired | ||
do_expire_timer(timer, state) | ||
end | ||
|
||
{:noreply, state, {:continue, rest}} | ||
end | ||
|
||
def handle_continue([], state) do | ||
# Logger.info("checkup complete") | ||
Process.send_after(self(), :checkup, 300_000) | ||
{:noreply, state, :hibernate} | ||
end | ||
|
||
@impl Quarrel.Listener | ||
def handle_guild_available(guild, state) do | ||
# for {_member_id, m} <- guild.members do | ||
# if state.config.accepted_role_id in m.roles do | ||
# ensure_new_user_timer(guild, m) | ||
# end | ||
# end | ||
|
||
{:noreply, state} | ||
end | ||
|
||
@impl Quarrel.Listener | ||
def handle_guild_member_update(old, new, state) do | ||
if state.config.accepted_role_id in (new.roles -- old.roles) do | ||
Logger.info("refreshing timer for #{new.user_id}") | ||
timer = ensure_new_user_timer(state.guild, new) | ||
refresh_looking_for_miata_timer(state.guild, timer) | ||
end | ||
|
||
if state.config.accepted_role_id in (old.roles -- new.roles) do | ||
Logger.info("refreshing timer for #{new.user_id}") | ||
timer = ensure_new_user_timer(state.guild, new) | ||
Repo.delete!(timer) | ||
end | ||
|
||
{:noreply, state} | ||
end | ||
|
||
def ensure_new_user_timer(guild, member) do | ||
case Repo.get_by(NewUsersTimer, | ||
discord_user_id: member.user_id, | ||
discord_guild_id: guild.id | ||
) do | ||
nil -> | ||
NewUsersTimer.changeset(%NewUsersTimer{}, %{ | ||
joined_at: DateTime.utc_now(), | ||
discord_user_id: member.user_id, | ||
discord_guild_id: guild.id | ||
}) | ||
|> Repo.insert!() | ||
|
||
timer -> | ||
timer | ||
end | ||
end | ||
|
||
def refresh_looking_for_miata_timer(_guild, timer) do | ||
NewUsersTimer.changeset(timer, %{ | ||
refreshed_at: DateTime.utc_now() | ||
}) | ||
|> Repo.update!() | ||
end | ||
|
||
def do_expire_timer(timer, state) do | ||
member = get_guild_member!(state.guild.id, timer.discord_user_id) | ||
|
||
Logger.info("expiring new user timer for member: #{inspect(member)}") | ||
|
||
Nostrum.Api.remove_guild_member(state.guild.id, timer.discord_user_id) | ||
catch | ||
_, error -> | ||
Logger.error("error doing user timer thing idk: #{inspect(error)}") | ||
delete(timer) | ||
end | ||
|
||
defp delete(timer) do | ||
case Repo.get(NewUsersTimer, timer.id) do | ||
nil -> :ok | ||
timer -> Repo.delete!(timer) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
priv/repo/migrations/20231223051435_add__new_timer_table.exs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
defmodule MiataBot.Repo.Migrations.Add_NewTimerTable do | ||
use Ecto.Migration | ||
|
||
def change do | ||
create table(:new_users) do | ||
add :refreshed_at, :utc_datetime | ||
add :joined_at, :utc_datetime | ||
add :discord_user_id, :string | ||
add :discord_guild_id, :string, default: "322080266761797633", null: false | ||
end | ||
|
||
create unique_index(:looking_for_miatas, [:discord_user_id, :discord_guild_id]) | ||
end | ||
end |