Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 66 additions & 71 deletions src/commands/faq.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,81 +141,76 @@ async def about(self, interaction: Interaction):
description="Outputs the date of the next Friday Night Games with food",
)
async def food(self, interaction: Interaction):
tz = pytz.timezone("Australia/Adelaide")
# Manually inputting dates
date_stack = [
tz.localize(dt.datetime(2025, 10, 24, 17)),
tz.localize(dt.datetime(2025, 10, 10, 17)),
tz.localize(dt.datetime(2025, 9, 19, 17)),
tz.localize(dt.datetime(2025, 8, 22, 17)),
tz.localize(dt.datetime(2025, 5, 30, 17)),
tz.localize(dt.datetime(2025, 3, 28, 17)),
]

# Checking if the tail date has already passed
curr_date = dt.datetime.now(tz)
if curr_date > date_stack[-1]:
while (
len(date_stack) > 0 and curr_date > date_stack[-1]
): # length check was added to prevent access of first element when list was empty - this would cause a compiler error
date_stack.pop()

# Printing next time for Games Night
if len(date_stack) == 0:
await interaction.response.send_message(
"The next Friday Night Games with food will be next year. Thank you for being a valued member!"
)
return
# Determining if games night is on the same day as day of function call
time_difference = date_stack[-1] - curr_date
if date_stack[-1].date() == curr_date.date():
time_difference_hours = floor(time_difference.seconds / 3600)
time_difference_minutes = ceil((time_difference.seconds % 3600) / 60)
message = ""
# Handle hours
if time_difference_hours == 1:
message += f"The next Friday Night Games with food is on today in {time_difference_hours} hour "
else:
message += f"The next Friday Night Games with food is on today in {time_difference_hours} hours "
# Handle minutes
if time_difference_minutes == 1:
message += f"and {time_difference_minutes} minute at 5pm. Join us in the Duck Lounge!"
try:
await interaction.response.defer()
tz = pytz.timezone("Australia/Adelaide")

fng_dates = cms.get_fng_food_dates()
date_stack = [d.astimezone(tz) for d in fng_dates]

# Checking if the tail date has already passed
curr_date = dt.datetime.now(tz)
if len(date_stack) > 0 and curr_date > date_stack[-1]:
while len(date_stack) > 0 and curr_date > date_stack[-1]:
date_stack.pop()

# Printing next time for Games Night
if len(date_stack) == 0:
await interaction.followup.send(
"The next Friday Night Games with food will be next year. Thank you for being a valued member!"
)
return
# Determining if games night is on the same day as day of function call
time_difference = date_stack[-1] - curr_date
if date_stack[-1].date() == curr_date.date():
time_difference_hours = floor(time_difference.seconds / 3600)
time_difference_minutes = ceil((time_difference.seconds % 3600) / 60)
message = ""
# Handle hours
if time_difference_hours == 1:
message += f"The next Friday Night Games with food is on today in {time_difference_hours} hour "
else:
message += f"The next Friday Night Games with food is on today in {time_difference_hours} hours "
# Handle minutes
if time_difference_minutes == 1:
message += f"and {time_difference_minutes} minute at 5pm. Join us in the Duck Lounge!"
else:
message += f"and {time_difference_minutes} minutes at 5pm. Join us in the Duck Lounge!"
await interaction.followup.send(message)
return

# Determining if games night is on the next day of function call
if date_stack[-1].date() == (curr_date + dt.timedelta(days=1)).date():
await interaction.followup.send(
"The next Friday Night Games with food is on tomorrow. Join us in the Duck Lounge at 5pm!"
)
return

# Determining whether date needs a st, nd, rd or rth
date_num = date_stack[-1].strftime("%d")
# Removing zero padding if present
if date_num[0] == "0":
date_num = date_num[1:]
date_day = date_stack[-1].strftime("%B")
time_difference_days = time_difference.days
if curr_date.time().hour >= 17:
time_difference_days += 1 # This allows for a more intuitive display of the difference in days
message = f"The next Friday Night Games with food will be held in {time_difference.days} days on the {date_num}"
if date_num in {"1", "21", "31"}:
message += "st "
elif date_num in {"2", "22"}:
message += "nd "
elif date_num in {"3", "23"}:
message += "rd "
else:
message += f"and {time_difference_minutes} minutes at 5pm. Join us in the Duck Lounge!"
await interaction.response.send_message(message)
message += "th "
message += f"of {date_day}"
await interaction.followup.send(message)
return

# Determining if games night is on the next day of function call
if date_stack[-1].date() == (curr_date + dt.timedelta(days=1)).date():
await interaction.response.send_message(
"The next Friday Night Games with food is on tomorrow. Join us in the Duck Lounge at 5pm!"
)
except Exception:
await interaction.followup.send("There was an error fetching FNG dates.")
return

# Determining whether date needs a st, nd, rd or rth
date_num = date_stack[-1].strftime("%d")
# Removing zero padding if present
if date_num[0] == "0":
date_num = date_num[1:]
date_day = date_stack[-1].strftime("%B")
time_difference_days = time_difference.days
if curr_date.time().hour >= 17:
time_difference_days += (
1 # This allows for a more intuitive display of the difference in days
)
message = f"The next Friday Night Games with food will be held in {time_difference.days} days on the {date_num}"
if date_num in {1, 21, 31}:
message += "st "
elif date_num in {2, 22}:
message += "nd "
elif date_num in {3, 23}:
message += "rd "
else:
message += "th "
message += f"of {date_day}"
await interaction.response.send_message(message)
return


class EventsGroup(app_commands.Group):
def __init__(self):
Expand Down
28 changes: 28 additions & 0 deletions src/utils/cms.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
COMMITTEE_ENDPOINT = "committee-members"
PROJECTS_ENDPOINT = "projects"
SPONSORS_ENDPOINT = "sponsors"
COMMON_EVENTS_ENDPOINT = "common-events"

_memory_cache = {}
_cache_times = {}
Expand Down Expand Up @@ -82,6 +83,33 @@ def get_cached_events(force: bool = False) -> Optional[Dict[str, Any]]:
return _get_cached(EVENTS_ENDPOINT, params=None, cache_key="events", force=force)


def get_fng_food_dates(force: bool = False) -> List[datetime]:
"""Return a list of upcoming Friday Night Games with Food dates from CMS"""
data = _get_cached(
COMMON_EVENTS_ENDPOINT,
params={"limit": 500},
cache_key="common_events",
force=force,
)
if not data:
return []
docs = data.get("docs", [])
dates = []
for doc in docs:
if "Friday Night Games with Food" in doc.get("name", ""):
upcoming = doc.get("upcomingDates", [])
for u in upcoming:
date_str = u.get("date")
dt = _parse_iso(date_str)
if dt:
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
dates.append(dt)
break
dates.sort(reverse=True)
return dates


def get_upcoming_events(limit: int = 50, force: bool = False) -> List[Dict[str, Any]]:
"""Return a list of upcoming events sorted by date."""
data = get_cached_events(force=force)
Expand Down