Add the cakeday loop and some of birthday functionality.

This commit is contained in:
2025-03-17 17:29:47 -04:00
parent 4d023e35f1
commit dae0d205e5
6 changed files with 114 additions and 2 deletions
+4 -1
View File
@@ -3,5 +3,8 @@
"reportOptionalMemberAccess": "warning",
"reportArgumentType": "information",
"reportAttributeAccessIssue": "warning"
}
},
"cSpell.words": [
"cakedays"
]
}
+10
View File
@@ -0,0 +1,10 @@
"""Initializing code for all loops."""
from nextcord.ext import commands
from cogs.loops.daily_loop import DailyLoop
def setup(bot: commands.Bot) -> None:
"""Add functions to bot."""
bot.add_cog(DailyLoop(bot))
+80
View File
@@ -0,0 +1,80 @@
"""Defines the daily loop that runs the Dakiny bot functions."""
from datetime import UTC, datetime, time
from typing import TYPE_CHECKING
from nextcord.ext import commands, tasks
from pytz import timezone
from sqlalchemy import select
from sqlalchemy.orm import Session
from logger import ocd_logger
from main import birthday_list
from settings import settings
if TYPE_CHECKING:
import nextcord
class DailyLoop(commands.Cog, name="Daily Loop"):
"""Class for performing daily functions."""
def __init__(self, bot: commands.Bot) -> None:
self.bot = bot
self.current_election = None
self.update_birthdays()
# pylint doesn't recognize that daily_loop is subclassed from tasks.loop.
self.daily_loop.start() # pylint: disable=no-member
@tasks.loop(time=time(hour=0, tzinfo=timezone("UTC")))
async def daily_loop(self) -> None:
"""Run daily repeated functions."""
self.update_birthdays()
await self.cakedays()
@daily_loop.before_loop
async def before_loop(self) -> None:
"""Actions run before the loop starts. Want to wait for bot to be ready and get the current cycle."""
await self.bot.wait_until_ready()
def update_birthdays(self) -> None:
"""Goes through database to collect all birthdays that are today. Adds user's id to birthday list."""
birthday_list.clear()
today = datetime.now(tz=UTC).date()
birthday = f"{today.month}/{today.day}"
stmt = select(UserBirthday.UserId).where(UserBirthday.Birthday == birthday)
with Session(engine) as session:
to_add = session.scalars(stmt)
birthday_list.extend(to_add.all())
async def cakedays(self) -> None:
"""
Loops through the guild's humans checking for joined_at dates that match today's date.
Sends a message saying happy cakeday.
"""
today = datetime.now(tz=UTC).date()
if (guild := self.bot.get_guild(settings.params.guild_id)) is None:
ocd_logger.warning("Guild not found in bot.")
return
if (announce_channel := guild.get_channel(settings.channel_ids.general)) is None or not isinstance(
announce_channel, nextcord.TextChannel
):
ocd_logger.warning("Set general channel isn't found or isn't a text channel.")
return
cakedays: list[nextcord.Member] = [
human
for human in guild.humans
if human.joined_at is not None and human.joined_at.month == today.month and human.joined_at.day == today.day
]
for member in cakedays:
years = today.year - member.joined_at.year
year_str = "years" if years > 1 else "year"
msg = f"Happy Cake day! <@{member.id}> joined the discord {years} {year_str} ago!"
await announce_channel.send(msg)
+10
View File
@@ -0,0 +1,10 @@
"""Creates logger for Agon bot."""
import logging
import sys
ocd_logger = logging.getLogger("default")
ocd_logger.setLevel(logging.INFO)
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(logging.Formatter("%(asctime)s:%(levelname)s:%(name)s: %(message)s"))
ocd_logger.addHandler(handler)
+1 -1
View File
@@ -28,7 +28,7 @@ def main() -> None:
# intents.guilds = True
# To enable the members privileged intent:
# intents.members = True
intents.members = True
bot = commands.Bot(intents=intents)
+9
View File
@@ -7,17 +7,26 @@ from dataclass_wizard import YAMLWizard
CONFIG_LOCATION = "conf/config.yaml"
@dataclass
class ChannelIds:
"""Class holds all channel ids needed by bot."""
general: int
@dataclass
class Params:
"""Class defines start parameters that shouldn't be changed."""
discord_token: str
guild_id: int
@dataclass
class Settings(YAMLWizard):
"""Class defines all configs required for off-cooldown-bot."""
channel_ids: ChannelIds
params: Params
def save(self) -> None: