mirror of
https://github.com/wlinator/luminara.git
synced 2024-10-02 20:23:12 +00:00
Refactor birthday module
This commit is contained in:
parent
ccf2b1236b
commit
05561495ab
5 changed files with 136 additions and 85 deletions
|
@ -17,6 +17,21 @@
|
|||
"admin_sync_error_title": "Sync Error",
|
||||
"admin_sync_title": "Sync Successful",
|
||||
"bet_limit": "❌ | **{0}** you cannot place any bets above **${1}**.",
|
||||
"birthday_check_started": "Daily birthday check started.",
|
||||
"birthday_check_skipped": "Birthday announcements in guild with ID {0} skipped: no birthday channel.",
|
||||
"birthday_check_success": "Birthday announcement Success! user/guild/chan ID: {0}/{1}/{2}",
|
||||
"birthday_check_error": "Birthday announcement skipped processing user/guild {0}/{1} | {2}",
|
||||
"birthday_check_finished": "Daily birthday check finished. {0} birthdays processed. {1} birthdays failed.",
|
||||
"birthday_add_invalid_date": "The date you entered is invalid.",
|
||||
"birthday_add_success_author": "Birthday Set",
|
||||
"birthday_add_success_description": "your birthday has been set to **{0} {1}**.",
|
||||
"birthday_delete_success_author": "Birthday Deleted",
|
||||
"birthday_delete_success_description": "your birthday has been deleted from this server.",
|
||||
"birthday_upcoming_author": "Upcoming Birthdays!",
|
||||
"birthday_upcoming_description_line": "🎂 {0} - {1}",
|
||||
"birthday_upcoming_no_birthdays_author": "No Upcoming Birthdays",
|
||||
"birthday_upcoming_no_birthdays": "there are no upcoming birthdays in this server.",
|
||||
"birthday_leap_year": "February 29",
|
||||
"case_case_field": "Case:",
|
||||
"case_case_field_value": "`{0}`",
|
||||
"case_duration_field": "Duration:",
|
||||
|
|
|
@ -85,6 +85,7 @@ class Constants:
|
|||
# birthdays
|
||||
BIRTHDAY_MESSAGES = JsonCache.read_json("birthday")["birthday_messages"]
|
||||
BIRTHDAY_MONTHS = JsonCache.read_json("birthday")["months"]
|
||||
BIRTHDAY_GIF_URL = "https://media1.tenor.com/m/NXvU9jbBUGMAAAAC/fireworks.gif"
|
||||
|
||||
|
||||
CONST = Constants()
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
import asyncio
|
||||
import random
|
||||
import datetime
|
||||
import pytz
|
||||
|
||||
import discord
|
||||
from discord.commands import SlashCommandGroup
|
||||
from discord.ext import commands, tasks
|
||||
from loguru import logger
|
||||
|
||||
from lib import checks, time
|
||||
from lib import checks
|
||||
from lib.constants import CONST
|
||||
from modules.birthdays import birthday
|
||||
from services.birthday_service import Birthday
|
||||
from services.config_service import GuildConfig
|
||||
from modules.birthdays import birthday, daily_check
|
||||
|
||||
|
||||
class Birthdays(commands.Cog):
|
||||
|
@ -18,9 +14,6 @@ class Birthdays(commands.Cog):
|
|||
self.client = client
|
||||
self.daily_birthday_check.start()
|
||||
|
||||
"""
|
||||
birthday module - slash command only
|
||||
"""
|
||||
birthday = SlashCommandGroup(
|
||||
name="birthday",
|
||||
description="Birthday commands.",
|
||||
|
@ -43,47 +36,9 @@ class Birthdays(commands.Cog):
|
|||
async def upcoming_birthdays(self, ctx):
|
||||
await birthday.upcoming(ctx)
|
||||
|
||||
@tasks.loop(hours=23, minutes=55)
|
||||
@tasks.loop(time=datetime.time(hour=12, minute=0, tzinfo=pytz.UTC)) # 12 PM UTC
|
||||
async def daily_birthday_check(self):
|
||||
wait_time = time.seconds_until(7, 0)
|
||||
logger.debug(
|
||||
f"Waiting until 7 AM Eastern for the daily birthday check: {round(wait_time)}s left.",
|
||||
)
|
||||
await asyncio.sleep(wait_time)
|
||||
|
||||
embed = discord.Embed(color=discord.Color.embed_background())
|
||||
embed.set_image(url="https://media1.tenor.com/m/NXvU9jbBUGMAAAAC/fireworks.gif")
|
||||
|
||||
for user_id, guild_id in Birthday.get_birthdays_today():
|
||||
try:
|
||||
guild = await self.client.fetch_guild(guild_id)
|
||||
member = await guild.fetch_member(user_id)
|
||||
guild_config = GuildConfig(guild.id)
|
||||
|
||||
if not guild_config.birthday_channel_id:
|
||||
logger.debug(
|
||||
f"Birthday announcements in guild with ID {guild.id} skipped: no birthday channel.",
|
||||
)
|
||||
return
|
||||
|
||||
message = random.choice(CONST.BIRTHDAY_MESSAGES)
|
||||
embed.description = message.format(member.name)
|
||||
channel = await self.client.get_or_fetch_channel(
|
||||
guild,
|
||||
guild_config.birthday_channel_id,
|
||||
)
|
||||
await channel.send(embed=embed, content=member.mention)
|
||||
logger.debug(
|
||||
f"Birthday announcement Success! user/guild/chan ID: {member.id}/{guild.id}/{channel.id}",
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
f"Birthday announcement skipped processing user/guild {user_id}/{guild_id} | {e}",
|
||||
)
|
||||
|
||||
# wait one second to avoid rate limits
|
||||
await asyncio.sleep(1)
|
||||
await daily_check.daily_birthday_check(self.client)
|
||||
|
||||
|
||||
def setup(client):
|
||||
|
|
|
@ -4,7 +4,8 @@ import datetime
|
|||
import discord
|
||||
from discord.ext import commands
|
||||
|
||||
from lib.embeds.info import BdayInfo
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
from lib.constants import CONST
|
||||
from services.birthday_service import Birthday
|
||||
|
||||
|
||||
|
@ -13,59 +14,75 @@ async def add(ctx, month, month_index, day):
|
|||
leap_year = 2020
|
||||
max_days = calendar.monthrange(leap_year, month_index)[1]
|
||||
|
||||
if not (1 <= day <= max_days):
|
||||
raise commands.BadArgument("the date you entered is invalid.")
|
||||
if not 1 <= day <= max_days:
|
||||
raise commands.BadArgument(CONST.STRINGS["birthday_add_invalid_date"])
|
||||
|
||||
date_str = f"{leap_year}-{month_index:02d}-{day:02d}"
|
||||
date_obj = datetime.datetime.strptime(date_str, "%Y-%m-%d")
|
||||
date_obj = datetime.datetime(leap_year, month_index, day)
|
||||
|
||||
birthday = Birthday(ctx.author.id, ctx.guild.id)
|
||||
birthday.set(date_obj)
|
||||
|
||||
await ctx.respond(embed=BdayInfo.set_month(ctx, month, day))
|
||||
embed = EmbedBuilder.create_success_embed(
|
||||
ctx,
|
||||
author_text=CONST.STRINGS["birthday_add_success_author"],
|
||||
description=CONST.STRINGS["birthday_add_success_description"].format(
|
||||
month,
|
||||
day,
|
||||
),
|
||||
show_name=True,
|
||||
)
|
||||
await ctx.respond(embed=embed)
|
||||
|
||||
|
||||
async def delete(ctx):
|
||||
"""Delete a user's birthday in a specific server."""
|
||||
birthday = Birthday(ctx.author.id, ctx.guild.id)
|
||||
birthday.delete()
|
||||
await ctx.respond(embed=BdayInfo.delete(ctx))
|
||||
Birthday(ctx.author.id, ctx.guild.id).delete()
|
||||
|
||||
embed = EmbedBuilder.create_success_embed(
|
||||
ctx,
|
||||
author_text=CONST.STRINGS["birthday_delete_success_author"],
|
||||
description=CONST.STRINGS["birthday_delete_success_description"],
|
||||
show_name=True,
|
||||
)
|
||||
await ctx.respond(embed=embed)
|
||||
|
||||
|
||||
async def upcoming(ctx):
|
||||
"""Get the upcoming birthdays for a specific server."""
|
||||
upcoming_birthdays = Birthday.get_upcoming_birthdays(ctx.guild.id)
|
||||
icon = ctx.guild.icon if ctx.guild.icon else "https://i.imgur.com/79XfsbS.png"
|
||||
|
||||
embed = discord.Embed(
|
||||
color=discord.Color.embed_background(),
|
||||
if not upcoming_birthdays:
|
||||
embed = EmbedBuilder.create_warning_embed(
|
||||
ctx,
|
||||
author_text=CONST.STRINGS["birthday_upcoming_no_birthdays_author"],
|
||||
description=CONST.STRINGS["birthday_upcoming_no_birthdays"],
|
||||
show_name=True,
|
||||
)
|
||||
embed.set_author(name="Upcoming Birthdays!", icon_url=icon)
|
||||
embed.set_thumbnail(url="https://i.imgur.com/79XfsbS.png")
|
||||
await ctx.respond(embed=embed)
|
||||
return
|
||||
|
||||
found_birthdays = 0
|
||||
for user_id, birthday in upcoming_birthdays:
|
||||
embed = EmbedBuilder.create_success_embed(
|
||||
ctx,
|
||||
author_text=CONST.STRINGS["birthday_upcoming_author"],
|
||||
description="",
|
||||
show_name=False,
|
||||
)
|
||||
embed.set_thumbnail(url=CONST.LUMI_LOGO_TRANSPARENT)
|
||||
|
||||
birthday_lines = []
|
||||
for user_id, birthday in upcoming_birthdays[:10]:
|
||||
try:
|
||||
member = await ctx.guild.fetch_member(user_id)
|
||||
name = member.name
|
||||
except discord.HTTPException:
|
||||
continue # skip user if not in guild
|
||||
|
||||
try:
|
||||
birthday_date = datetime.datetime.strptime(birthday, "%m-%d")
|
||||
formatted_birthday = birthday_date.strftime("%B %-d")
|
||||
except ValueError:
|
||||
# leap year error
|
||||
formatted_birthday = "February 29"
|
||||
|
||||
embed.add_field(
|
||||
name=f"{name}",
|
||||
value=f"🎂 {formatted_birthday}",
|
||||
inline=False,
|
||||
birthday_lines.append(
|
||||
CONST.STRINGS["birthday_upcoming_description_line"].format(
|
||||
member.name,
|
||||
formatted_birthday,
|
||||
),
|
||||
)
|
||||
except (discord.HTTPException, ValueError):
|
||||
continue
|
||||
|
||||
found_birthdays += 1
|
||||
if found_birthdays >= 5:
|
||||
break
|
||||
|
||||
embed.description = "\n".join(birthday_lines)
|
||||
await ctx.respond(embed=embed)
|
||||
|
|
63
modules/birthdays/daily_check.py
Normal file
63
modules/birthdays/daily_check.py
Normal file
|
@ -0,0 +1,63 @@
|
|||
import asyncio
|
||||
import random
|
||||
from loguru import logger
|
||||
from lib.constants import CONST
|
||||
from services.birthday_service import Birthday
|
||||
from services.config_service import GuildConfig
|
||||
from lib.embed_builder import EmbedBuilder
|
||||
|
||||
|
||||
async def daily_birthday_check(client):
|
||||
logger.info(CONST.STRINGS["birthday_check_started"])
|
||||
birthdays_today = Birthday.get_birthdays_today()
|
||||
processed_birthdays = 0
|
||||
failed_birthdays = 0
|
||||
|
||||
if birthdays_today:
|
||||
for user_id, guild_id in birthdays_today:
|
||||
try:
|
||||
guild = await client.fetch_guild(guild_id)
|
||||
member = await guild.fetch_member(user_id)
|
||||
guild_config = GuildConfig(guild.id)
|
||||
|
||||
if not guild_config.birthday_channel_id:
|
||||
logger.debug(
|
||||
CONST.STRINGS["birthday_check_skipped"].format(guild.id),
|
||||
)
|
||||
continue
|
||||
|
||||
message = random.choice(CONST.BIRTHDAY_MESSAGES)
|
||||
embed = EmbedBuilder.create_success_embed(
|
||||
None,
|
||||
author_text="Happy Birthday!",
|
||||
description=message.format(member.name),
|
||||
show_name=False,
|
||||
)
|
||||
embed.set_image(url=CONST.BIRTHDAY_GIF_URL)
|
||||
|
||||
channel = await guild.fetch_channel(guild_config.birthday_channel_id)
|
||||
await channel.send(embed=embed, content=member.mention)
|
||||
logger.debug(
|
||||
CONST.STRINGS["birthday_check_success"].format(
|
||||
member.id,
|
||||
guild.id,
|
||||
channel.id,
|
||||
),
|
||||
)
|
||||
processed_birthdays += 1
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
CONST.STRINGS["birthday_check_error"].format(user_id, guild_id, e),
|
||||
)
|
||||
failed_birthdays += 1
|
||||
|
||||
# wait one second to avoid rate limits
|
||||
await asyncio.sleep(1)
|
||||
|
||||
logger.info(
|
||||
CONST.STRINGS["birthday_check_finished"].format(
|
||||
processed_birthdays,
|
||||
failed_birthdays,
|
||||
),
|
||||
)
|
Loading…
Reference in a new issue