didier/didier/data/embeds/hydra/menu.py

132 lines
3.7 KiB
Python
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

from datetime import date
from enum import Enum
from typing import Optional, cast
import discord
from overrides import overrides
from pydantic import BaseModel
from didier.data.embeds.base import EmbedPydantic
from didier.utils.discord.colours import ghent_university_blue, ghent_university_yellow
from didier.utils.types.datetime import int_to_weekday
from didier.utils.types.string import leading
__all__ = ["Menu", "no_menu_found"]
class _MealKind(str, Enum):
FISH = "fish"
MEAT = "meat"
SOUP = "soup"
VEGAN = "vegan"
VEGETARIAN = "vegetarian"
class _MealType(str, Enum):
COLD = "cold"
MAIN = "main"
SIDE = "side"
class _Meal(BaseModel):
"""Model for an item on the menu"""
kind: _MealKind
name: str
price: str
type: _MealType
class Menu(EmbedPydantic):
"""Embed that shows the menu in Ghent University restaurants"""
meals: list[_Meal] = []
open: bool
vegetables: list[str] = []
message: Optional[str] = None
def _get_dutch_meal_prefix(self, meal: _Meal) -> str:
if meal.kind == _MealKind.MEAT:
prefix = "Vlees"
elif meal.kind == _MealKind.FISH:
prefix = "Vis"
elif meal.kind == _MealKind.VEGETARIAN:
prefix = "Vegetarisch"
else:
prefix = "Vegan"
return prefix
def _get_soups(self) -> str:
acc = ""
for meal in self.meals:
if meal.kind == _MealKind.SOUP:
acc += f"{meal.name} ({meal.price})\n"
return acc.strip()
def _get_main_courses(self) -> str:
acc = ""
for meal in self.meals:
if meal.type != _MealType.MAIN:
continue
prefix = self._get_dutch_meal_prefix(meal)
acc += f"* {prefix}: {meal.name} ({meal.price})\n"
return acc.strip()
def _get_cold_meals(self) -> str:
acc = ""
for meal in self.meals:
if meal.type == _MealType.COLD:
acc += f"* {self._get_dutch_meal_prefix(meal)}: {meal.name} ({meal.price})\n"
return acc.strip()
def _closed_embed(self, embed: discord.Embed) -> discord.Embed:
embed.colour = ghent_university_yellow()
embed.description = "The restaurants are closed today."
return embed
def _regular_embed(self, embed: discord.Embed) -> discord.Embed:
if soups := self._get_soups():
embed.add_field(name="🥣 Soep", value=soups, inline=False)
if mains := self._get_main_courses():
embed.add_field(name="🍴 Hoofdgerechten", value=mains, inline=False)
if cold := self._get_cold_meals():
embed.add_field(name="Koud", value=cold, inline=False)
if vegetables := "\n".join(list(sorted(self.vegetables))):
embed.add_field(name="🥦 Groenten", value=vegetables, inline=False)
return embed
@overrides
def to_embed(self, **kwargs) -> discord.Embed:
day_dt: date = cast(date, kwargs.get("day_dt"))
weekday = int_to_weekday(day_dt.weekday())
formatted_date = f"{leading('0', str(day_dt.day))}/{leading('0', str(day_dt.month))}/{day_dt.year}"
embed = discord.Embed(title=f"Menu - {weekday} {formatted_date}", colour=ghent_university_blue())
embed = self._regular_embed(embed) if self.open else self._closed_embed(embed)
if self.message:
embed.add_field(name="📣 Extra Mededeling", value=self.message, inline=False)
return embed
def no_menu_found(day_dt: date) -> discord.Embed:
"""Return a different embed if no menu could be found"""
embed = discord.Embed(title="Menu", colour=discord.Colour.red())
embed.description = f"Unable to retrieve menu for {day_dt.strftime('%d/%m/%Y')}."
return embed