From b5f30a8b2d1f218c3625b6406103338a2d1785c8 Mon Sep 17 00:00:00 2001 From: zevaryx Date: Wed, 20 Apr 2022 11:03:56 -0600 Subject: [PATCH] Add autokick, closes jarvis-bot#74 --- jarvis_tasks/__init__.py | 12 ++++++- jarvis_tasks/tasks/autokick.py | 66 ++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 jarvis_tasks/tasks/autokick.py diff --git a/jarvis_tasks/__init__.py b/jarvis_tasks/__init__.py index 7744455..aabb42b 100644 --- a/jarvis_tasks/__init__.py +++ b/jarvis_tasks/__init__.py @@ -8,7 +8,16 @@ from jarvis_core.log import get_logger from jarvis_tasks import const from jarvis_tasks.config import TaskConfig -from jarvis_tasks.tasks import ban, lock, lockdown, reddit, reminder, twitter, warning +from jarvis_tasks.tasks import ( + autokick, + ban, + lock, + lockdown, + reddit, + reminder, + twitter, + warning, +) __version__ = const.__version__ logger = None @@ -43,6 +52,7 @@ async def _start(config: Optional[str] = "config.yaml") -> None: try: logger.debug("Starting tasks") functions = [ + autokick.autokick, ban.unban, lock.unlock, lockdown.lift, diff --git a/jarvis_tasks/tasks/autokick.py b/jarvis_tasks/tasks/autokick.py new file mode 100644 index 0000000..ef83932 --- /dev/null +++ b/jarvis_tasks/tasks/autokick.py @@ -0,0 +1,66 @@ +"""JARVIS autokick tasks.""" +import asyncio +import logging +from datetime import datetime, timedelta, timezone + +from dis_snek import Snake +from jarvis_core.db import q +from jarvis_core.db.models import Setting + +logger = logging.get_logger(__name__) + +resync = {} + + +async def autokick(bot: Snake) -> None: + """ + Autokick unverified usersself. + + Args: + bot: Bot instance + """ + logger.debug("Starting Task-autokick") + + while True: + autokicks = Setting.find(q(setting="autokick", value__exists=True)) + async for auto in autokicks: + if auto.value <= 0: + logger.warn("Autokick setting <= 0, deleting") + await auto.delete() + continue + verified = await Setting.find_one( + q(setting="verified", value__exists=True, guild=auto.guild) + ) + unverified = await Setting.find_one( + q(setting="unverified", value__exists=True, guild=auto.guild) + ) + if not verified or not unverified: + logger.debug( + f"Guild {auto.guild} is missing one of: verified, unverified. Ignoring" + ) + continue + guild = await bot.fetch_guild(auto.guild) + if not guild: + logger.warn(f"Guild {auto.guild} no longer exists, deleting setting") + await auto.delete() + await verified.delete() + await unverified.delete() + continue + + if guild.id not in resync or resync[guild.id] >= datetime.now(tz=timezone.utc): + logger.info(f"Guild {guild.id} out of date, resyncing") + limit = 1000 + guild_id = guild.id + after = None + while members := await bot.http.list_members( + guild_id=guild_id, limit=limit, after=after + ): + after = members[-1].id + await asyncio.sleep(0.2) + + role = await guild.fetch_role(unverified.value) + for member in role.members: + if member.joined_at + timedelta(days=auto.value) >= datetime.now(tz=timezone.utc): + await member.kick(reason="Failed to verify in {auto.value} days") + + await asyncio.sleep(14400)