import discord import datetime from discord.ext import commands, tasks from utils.sql_commands import DatabaseManager from dotenv import dotenv_values def check(author): def inner_check(message): return message.author == author return inner_check class Birthday(commands.Cog): def __init__(self, client): self.client = client self.db = DatabaseManager("") self.birthday_checks = {} async def cog_load(self): self.check_birthdays.start() async def cog_unload(self): self.check_birthdays.cancel() @tasks.loop(seconds=60*60*24) # daily async def check_birthdays(self): today = datetime.date.today() for guild in self.client.guilds: guild_id = guild.id for member in guild.members: user_id = member.id user_data = self.db.fetch_one("SELECT * FROM users WHERE ID = %s", (user_id,)) if user_data is None or user_data.get("birthday") is None: continue birthday = datetime.datetime.strptime(user_data.get("birthday"), "%Y-%m-%d").date() if birthday.month == today.month and birthday.day == today.day: # send birthday message try: channel = guild.text_channels[0] await channel.send(f"Happy birthday, {member.mention}! 🎉") except discord.Forbidden: continue except discord.HTTPException: continue # give birthday reward reward = self.db.fetch_one("SELECT * FROM rewards WHERE type = 'birthday'") if reward is not None: try: await self.client.get_cog("Economy").add_points(user_id, guild_id, reward.get("amount"), "birthday reward") except Exception as e: print(f"Error giving birthday reward: {e}") # give birthday star role role = discord.utils.get(guild.roles, name="Birthday Star") if role is not None: try: await member.add_roles(role) except discord.Forbidden: continue except discord.HTTPException: continue # log birthday reward try: self.db.execute_query("INSERT INTO logs (guild_id, user_id, type, message) VALUES (%s, %s, 'birthday_reward', 'claimed birthday reward')", (guild_id, user_id)) except Exception as e: print(f"Error logging birthday reward: {e}") @check_birthdays.before_loop async def before_check_birthdays(self): await self.client.wait_until_ready() @commands.command(name="setbirthday", aliases=["sb"]) async def setbirthday(self, ctx, month: int, day: int): if month < 1 or month > 12 or day < 1 or day > 31: return await ctx.send("Invalid date") user_id = ctx.author.id user_data = self.db.fetch_one("SELECT * FROM users WHERE ID = %s", (user_id,)) if user_data is not None and user_data.get("birthday") is not None: return await ctx.send("You've already set your birthday") self.db.execute_query("UPDATE users SET birthday = %s WHERE ID = %s", (f"{datetime.date.today().year}-{month}-{day}", user_id)) await ctx.send("Your birthday has been set") @commands.command(name="claimbirthday", aliases=["cb"]) async def claimbirthday(self, ctx): user_id = ctx.author.id user_data = self.db.fetch_one("SELECT * FROM users WHERE ID = %s", (user_id,)) if user_data is None or user_data.get("birthday") is None: return await ctx.send("You haven't set your birthday") today = datetime.date.today() birthday = datetime.datetime.strptime(user_data.get("birthday"), "%Y-%m-%d").date() if birthday.month != today.month or birthday.day != today.day: return await ctx.send("It's not your birthday") reward = self.db.fetch_one("SELECT * FROM rewards WHERE type = 'birthday'") if reward is None: return await ctx.send("No birthday reward set") await self.client.get_cog("Economy").add_points(user_id, ctx.guild.id, reward.get("amount"), "birthday reward") await ctx.send("You've claimed your birthday reward") @commands.command(name="listbirthdays", aliases=["lb"]) async def listbirthdays(self, ctx): today = datetime.date.today() birthdays = [] for guild in self.client.guilds: for member in guild.members: user_id = member.id user_data = self.db.fetch_one("SELECT * FROM users WHERE ID = %s", (user_id,)) if user_data is None or user_data.get("birthday") is None: continue birthday = datetime.datetime.strptime(user_data.get("birthday"), "%Y-%m-%d").date() if birthday.month == today.month and birthday.day == today.day: birthdays.append(member.mention) if not birthdays: await ctx.send("No birthdays today") else: await ctx.send(f"Happy birthday to {', '.join(birthdays)}! 🎉")