Skip to content

Instantly share code, notes, and snippets.

@Kanin
Created January 15, 2022 12:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kanin/07072bf7b17ce66714ebcb3ee7c99412 to your computer and use it in GitHub Desktop.
Save Kanin/07072bf7b17ce66714ebcb3ee7c99412 to your computer and use it in GitHub Desktop.
from datetime import datetime, timezone
import discord
from discord import Option, OptionChoice
from discord.ext import commands, tasks
from bot import Bot
month_choices = [
OptionChoice(name="January", value=1),
OptionChoice(name="February", value=2),
OptionChoice(name="March", value=3),
OptionChoice(name="April", value=4),
OptionChoice(name="May", value=5),
OptionChoice(name="June", value=6),
OptionChoice(name="July", value=7),
OptionChoice(name="August", value=8),
OptionChoice(name="September", value=9),
OptionChoice(name="October", value=10),
OptionChoice(name="November", value=11),
OptionChoice(name="December", value=12)
]
class Confirm(discord.ui.View):
def __init__(self):
super().__init__()
self.value = None
@staticmethod
async def disable_buttons(interaction: discord.Interaction):
view = discord.ui.View.from_message(interaction.message)
for child in view.children:
child.disabled = True
await interaction.response.edit_message(view=view)
@discord.ui.button(label="Confirm", style=discord.ButtonStyle.green)
async def confirm(self, button: discord.ui.Button, interaction: discord.Interaction):
await self.disable_buttons(interaction)
self.value = True
self.stop()
@discord.ui.button(label="Deny", style=discord.ButtonStyle.red)
async def cancel(self, button: discord.ui.Button, interaction: discord.Interaction):
await self.disable_buttons(interaction)
self.value = False
self.stop()
class Birthdays(commands.Cog):
def __init__(self, bot):
self.bot: Bot = bot
self.day = 0
self.first = True
self.birthday_handler.start()
def cog_unload(self):
self.birthday_handler.cancel()
@tasks.loop(hours=1)
async def birthday_handler(self): # sourcery no-metrics
now = datetime.utcnow()
if self.day != now.day:
self.day = now.day
self.first = True
data = await self.bot.pool.fetch(
"SELECT * FROM birthdays WHERE extract(month from birthday) = $1 AND extract(day from birthday) = $2",
now.month,
now.day
)
if not data:
if (now.year % 400 == 0) or (now.year % 100 != 0) and (now.year % 4 == 0): # Check if it's a leap year
return
if now.day == 28 and now.month == 2: # We're going to celebrate on the 28th
data = await self.bot.pool.fetch(
"SELECT * FROM birthdays WHERE extract(month from birthday) = 2 AND extract(day from birthday) = 29"
)
if not data:
return
guild: discord.Guild = self.bot.get_guild(694641646780022818)
channel: discord.TextChannel = guild.get_channel(931864362682024006)
pings: discord.Role = guild.get_role(931888496602386493)
age18_20: discord.Role = guild.get_role(929838790506332181)
age21_25: discord.Role = guild.get_role(929838791336792154)
age26_30: discord.Role = guild.get_role(929838792188239892)
age31_40: discord.Role = guild.get_role(929838793056481330)
age41: discord.Role = guild.get_role(929838793895321610)
announcements = []
unbans = 0
left_birthdays = 0
for birthday in data:
age = int((datetime.now().replace(tzinfo=timezone.utc) - birthday["birthday"]).days / 365.25)
if age == birthday["age"]:
continue
if age < 18:
return
if birthday["age"] < 18:
unbans += 1
user: discord.User = self.bot.get_user(birthday["user_id"])
await guild.unban(user, reason="They are now 18!")
member: discord.Member = guild.get_member(birthday["user_id"])
if member:
if 21 <= age <= 25 and age21_25 not in member.roles:
await member.remove_roles(age18_20)
await member.add_roles(age21_25)
elif 26 <= age <= 30 and age26_30 not in member.roles:
await member.remove_roles(age21_25)
await member.add_roles(age26_30)
elif 31 <= age <= 40 and age31_40 not in member.roles:
await member.remove_roles(age26_30)
await member.add_roles(age31_40)
elif age >= 41 and age41 not in member.roles:
await member.remove_roles(age31_40)
await member.add_roles(age41)
if birthday["announce"] is True:
if self.first is True:
announcements.append(member)
else:
em = discord.Embed(colour=0x912252)
em.set_author(name="Another birthday!")
em.description = f"Everyone wish {member.mention} `[{member}]` a happy birthday!"
await channel.send(embed=em, content=pings.mention)
else:
left_birthdays += 1
await self.bot.pool.execute("UPDATE birthdays SET age=$1 WHERE user_id=$2", age, birthday["user_id"])
if announcements:
em = discord.Embed(colour=0x912252)
if len(announcements) == 1:
em.set_author(name="We have a birthday today!")
else:
em.set_author(name="We have some birthdays today!")
em.set_footer(text="Everyone wish them a happy birthday!")
em.description = "\n".join(f"{x.mention} `[{x}]`" for x in announcements)
em.description += f"\n\nIn addition I have unbanned {unbans} people for turning 18 today" \
f" and {left_birthdays} people that have left are celebrating birthdays today!"
await channel.send(embed=em, content=pings.mention)
# , guild_ids=[694641646780022818]
@commands.slash_command(description="Set your birthday in the database!", guild_ids=[694641646780022818])
async def birthday(self, ctx,
year: Option(int, description="The year you were born"),
month: Option(int, choices=month_choices, description="The month you were born"),
day: Option(int, description="The day you were born")):
await ctx.respond("Handling your data...", ephemeral=True)
data = await self.bot.pool.fetchrow("SELECT * FROM birthdays WHERE user_id=$1", ctx.author.id)
if data:
return await ctx.followup.send("You've already submitted your birthday.", ephemeral=True)
if year < 1950 or year > datetime.utcnow().year:
return await ctx.followup.send("Invalid year, must be after 1950 and before this year.. whore.", ephemeral=True)
if day < 1:
return await ctx.followup.send("Day can't be less than one.. slut.", ephemeral=True)
try:
birthday_datetime = datetime(year=year, month=month, day=day).replace(tzinfo=timezone.utc)
except ValueError as e:
return await ctx.followup.send(str(e).capitalize(), ephemeral=True)
age = int((datetime.now().replace(tzinfo=timezone.utc) - birthday_datetime).days / 365.25)
jailbait = ctx.guild.get_role(694641646889074805)
age18_20 = ctx.guild.get_role(929838790506332181)
age21_25 = ctx.guild.get_role(929838791336792154)
age26_30 = ctx.guild.get_role(929838792188239892)
age31_40 = ctx.guild.get_role(929838793056481330)
age41 = ctx.guild.get_role(929838793895321610)
await self.bot.pool.execute(
"INSERT INTO birthdays (user_id, birthday, age) VALUES ($1, $2, $3)",
ctx.author.id,
birthday_datetime,
age
)
await ctx.author.remove_roles(*[age18_20, age21_25, age26_30, age31_40, age41])
if age < 18:
return await ctx.author.add_roles(jailbait)
if 18 <= age <= 20:
await ctx.author.add_roles(age18_20)
elif 21 <= age <= 25:
await ctx.author.add_roles(age21_25)
elif 26 <= age <= 30:
await ctx.author.add_roles(age26_30)
elif 31 <= age <= 40:
await ctx.author.add_roles(age31_40)
else:
await ctx.author.add_roles(age41)
view = Confirm()
await ctx.followup.send(
"Okay I have updated the database, would you like your birthday to be public?",
ephemeral=True,
view=view
)
await view.wait()
if view.value is None:
await ctx.followup.send("Timed out, use *coming soon* to toggle this feature!", ephemeral=True)
elif view.value is False:
await ctx.followup.send("Okay, you can use *coming soon* to change this any time!", ephemeral=True)
else:
await self.bot.pool.execute("UPDATE birthdays SET announce=true WHERE user_id=$1", ctx.author.id)
await ctx.followup.send("Okay I will announce your birthday!", ephemeral=True)
@commands.Cog.listener()
async def on_member_join(self, member: discord.Member):
age = await self.bot.pool.fetchval("SELECT age FROM birthdays WHERE user_id=$1", member.id)
if not age:
return
guild: discord.Guild = member.guild
if guild.id != 694641646780022818:
return
jailbait = guild.get_role(694641646889074805)
age18_20 = guild.get_role(929838790506332181)
age21_25 = guild.get_role(929838791336792154)
age26_30 = guild.get_role(929838792188239892)
age31_40 = guild.get_role(929838793056481330)
age41 = guild.get_role(929838793895321610)
if age < 18:
return await member.add_roles(jailbait)
if 18 <= age <= 20:
await member.add_roles(age18_20)
elif 21 <= age <= 25:
await member.add_roles(age21_25)
elif 26 <= age <= 30:
await member.add_roles(age26_30)
elif 31 <= age <= 40:
await member.add_roles(age31_40)
else:
await member.add_roles(age41)
def setup(bot):
bot.add_cog(Birthdays(bot))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment