Created
January 15, 2022 12:41
-
-
Save Kanin/07072bf7b17ce66714ebcb3ee7c99412 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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