Author SHA1 Message Date
imcompiling e1a7eae355 Fix birthday clear.
build_develop / build (push) Failing after 23s
build_latest / build (push) Failing after 20s
2025-03-17 21:31:44 -04:00
imcompiling 5b77abff13 Add birthday clear command. (not removing from database right now).
build_develop / build (push) Failing after 18s
2025-03-17 18:36:29 -04:00
imcompiling 467c76671b Add the message listener. 2025-03-17 18:27:31 -04:00
imcompiling 8499ae0a78 Remove hi cog. 2025-03-17 18:24:12 -04:00
imcompiling ea3204d890 Fix cog loading. 2025-03-17 18:21:19 -04:00
imcompiling e4881a74d4 Ignore the database. 2025-03-17 18:21:13 -04:00
imcompiling 892f873320 Create birthday set command. 2025-03-17 18:16:44 -04:00
imcompiling a5c1359fac Add randomized presence with mythic plus theme. 2025-03-17 17:59:51 -04:00
8 changed files with 187 additions and 26 deletions
+3 -1
View File
@@ -127,4 +127,6 @@ dmypy.json
# logging
nextcord.log
outputs/
outputs/
database.db
+2 -2
View File
@@ -2,11 +2,11 @@
from nextcord.ext import commands
from cogs.commands.hi import HiCog
from cogs.commands.birthday import BirthdayCog
# This function will be called when this extension is loaded.
# It is necessary to add these functions to the bot.
def setup(bot: commands.Bot) -> None:
"""Add all command classes to bot."""
bot.add_cog(HiCog(bot))
bot.add_cog(BirthdayCog())
+94
View File
@@ -0,0 +1,94 @@
"""Contains commands for birthday feature."""
from datetime import datetime
import nextcord
from nextcord.ext import commands
from pytz import UTC
from sqlmodel import Session, col, select
from database.db import engine
from database.models import UserBirthday
from main import birthday_list
class BirthdayCog(commands.Cog, name="Birthday Commands"):
"""Class holds birthday commands."""
@nextcord.slash_command(guild_ids=[1000247361639030804, 822199658306076672])
async def birthday(self, interaction: nextcord.Interaction) -> None:
"""Parent slash command for birthday. Never called."""
@birthday.subcommand(description="Set your birthday month and day for birthday fun!")
async def set(
self,
interaction: nextcord.Interaction,
month: int = nextcord.SlashOption(required=True, min_value=1, max_value=12, description="Your birth month."),
day: int = nextcord.SlashOption(required=True, min_value=1, max_value=31, description="Your birth day."),
) -> None:
"""
Set a user's birthday in the database. If birthday is today, adds to the birthday_list.
Args:
interaction (nextcord.Interaction): Interaction that invoked the command.
month (int, optional): The month a user was born. Is SlashOption.
day (int, optional): The day a user was born. Is SlashOption.
"""
# Ensure that a person used the command.
if interaction.user is None:
return
await interaction.response.defer(ephemeral=True)
# check if valid day
today = datetime.now(tz=UTC)
try:
birthday = datetime(today.year, month, day, tzinfo=UTC)
except ValueError:
await interaction.followup.send(f"Invalid date: {month}/{day}.", ephemeral=True)
return
# If the birthday is today, add to birthday_list
if today.date() == birthday.date():
birthday_list.append(interaction.user.id)
new_birthday = UserBirthday(user_id=interaction.user.id, month=month, day=day)
with Session(engine) as session:
stmt = select(UserBirthday).where(UserBirthday.user_id == interaction.user.id)
if (new_birthday := session.scalar(stmt)) is None:
new_birthday = UserBirthday(user_id=interaction.user.id, month=month, day=day)
session.add(new_birthday)
else:
new_birthday.month = month
new_birthday.day = day
session.commit()
await interaction.followup.send(f"Birthday set to {month}/{day}.", ephemeral=True)
@birthday.subcommand(description="Remove yourself from the birthday list.")
async def clear(self, interaction: nextcord.Interaction) -> None:
"""
Remove the user from the birthday database.
Args:
interaction (nextcord.Interaction): Interaction that invoked the command.
"""
# Ensure that a person used the command.
if interaction.user is None:
return
if interaction.user.id in birthday_list:
birthday_list.remove(interaction.user.id)
with Session(engine) as session:
stmt = select(UserBirthday).where(col(UserBirthday.user_id) == interaction.user.id)
if (user := session.scalar(stmt)) is None:
await interaction.response.send_message("No birthday to clear.", ephemeral=True)
return
session.delete(user)
session.commit()
await interaction.response.send_message("Birthday cleared.", ephemeral=True)
-22
View File
@@ -1,22 +0,0 @@
"""Example command file."""
import nextcord
from nextcord.ext import commands
class HiCog(commands.Cog, name="Test commands."):
"""Class holds commands for testing."""
def __init__(self, bot: nextcord.Bot) -> None:
self.bot = bot
@nextcord.slash_command()
async def hi(self, interaction: nextcord.Interaction) -> None:
"""
Says hi.
Args:
interaction (nextcord.Interaction): Interaction to reply to.
"""
await interaction.response.send_message("Hi!", ephemeral=True)
+2
View File
@@ -2,9 +2,11 @@
from nextcord.ext import commands
from cogs.loops.bot_presence import BotPresence
from cogs.loops.daily_loop import DailyLoop
def setup(bot: commands.Bot) -> None:
"""Add functions to bot."""
bot.add_cog(DailyLoop(bot))
bot.add_cog(BotPresence(bot))
+44
View File
@@ -0,0 +1,44 @@
"""Functions for controlling the bot's presence. Also contains the loop."""
import random
import nextcord
from nextcord.ext import commands, tasks
class BotPresence(commands.Cog, name="Bot Presence"):
"""Class for bot presence functions."""
def __init__(self, bot: commands.Bot) -> None:
self.bot = bot
@commands.Cog.listener()
async def on_ready(self) -> None:
"""Start the loop when bot is ready."""
await self.bot.wait_until_ready()
self.periodic_change_presence.start()
@tasks.loop(minutes=30)
async def periodic_change_presence(self) -> None:
"""Loops every 30 minutes and changes presence."""
await self.change_presence()
async def change_presence(self) -> None:
"""Randomly chooses a presence and updates bot's presence."""
dungeons = [
"Cinderbrew Meadery",
"Darkflame Cleft",
"The Rookery",
"Priory of the Sacred Flame",
"Operation: Floodgate",
"The MOTHERLODE!!",
"Theater of Pain",
"Operation: Mechagon - Workshop",
]
dungeon = random.choice(dungeons) # noqa: S311
plus = random.randint(2, 12) # noqa: S311
presence = f"Running +{plus} {dungeon}"
await self.bot.change_presence(activity=nextcord.CustomActivity(presence))
+41
View File
@@ -0,0 +1,41 @@
"""Defines cog for on message listener."""
import nextcord
from nextcord.ext import commands
from main import birthday_list
class SubmissionListener(commands.Cog, name="Message Listener"):
"""Sets up message listener."""
def __init__(self, bot: commands.Bot) -> None:
self.bot = bot
@commands.Cog.listener()
async def on_message(self, message: nextcord.Message) -> None:
"""Listen for message creation. Adds score and attachments to submission."""
# don't want to process any messages from bot.
if message.author.id == self.bot.user.id: # type: ignore reportOptionalMemberAccess
return
await birthday_action(message)
# This function will be called when this extension is loaded.
# It is necessary to add these functions to the bot.
def setup(bot: commands.Bot) -> None:
"""Add function to bot."""
bot.add_cog(SubmissionListener(bot))
async def birthday_action(message: nextcord.Message) -> None:
"""
Check a message's author and mentions to see if they are in the birthday list.
Args:
message (nextcord.Message): The message to check for a birthday person.
"""
if message.author.id in birthday_list or bool(set(message.raw_mentions) & set(birthday_list)):
await message.add_reaction("🎂")
+1 -1
View File
@@ -39,7 +39,7 @@ def main() -> None:
# Get the modules of all cogs whose directory structure is ./cogs/<module_name>
for folder in pathlib.Path("cogs").iterdir():
bot.load_extension(f"cogs.{folder}")
bot.load_extension(f"cogs.{folder.name}")
@bot.listen()
async def on_ready() -> None: