diff --git a/uqcsbot/advent.py b/uqcsbot/advent.py index a711934..fa0a49f 100644 --- a/uqcsbot/advent.py +++ b/uqcsbot/advent.py @@ -1,6 +1,6 @@ import io import os -from datetime import datetime +from datetime import datetime, timedelta from random import choices from typing import Any, Callable, Dict, Iterable, List, Optional, Literal import requests @@ -141,7 +141,7 @@ class LeaderboardView(discord.ui.View): TRUNCATED_COUNT = 20 - TIMEOUT = 180 # seconds + TIMEOUT = timedelta(hours=24).total_seconds() def __init__( self, diff --git a/uqcsbot/utils/advent_utils.py b/uqcsbot/utils/advent_utils.py index a7d294b..56daccd 100644 --- a/uqcsbot/utils/advent_utils.py +++ b/uqcsbot/utils/advent_utils.py @@ -6,13 +6,14 @@ Dict, Optional, Callable, - NamedTuple, Tuple, cast, ) +from dataclasses import dataclass from collections import defaultdict from datetime import datetime, timedelta from zoneinfo import ZoneInfo +from functools import lru_cache from io import BytesIO import PIL.Image @@ -33,8 +34,16 @@ Times = Dict[Star, Seconds] Delta = Optional[Seconds] Json = Dict[str, Any] + Colour = str -ColourFragment = NamedTuple("ColourFragment", [("text", str), ("colour", Colour)]) + + +@dataclass(frozen=True) +class ColourFragment: + text: str + colour: Colour + + Leaderboard = list[str | ColourFragment] # Puzzles are unlocked at midnight EST. @@ -437,6 +446,7 @@ def _isolate_leaderboard_layers( return spaces_str, cast(Dict[str, Any], layers) +@lru_cache(maxsize=16) def render_leaderboard_to_image(leaderboard: Leaderboard) -> bytes: spaces, layers = _isolate_leaderboard_layers(leaderboard) @@ -462,7 +472,7 @@ def render_leaderboard_to_image(leaderboard: Leaderboard) -> bytes: buf = BytesIO() img.save(buf, format="PNG", optimize=True) - return buf.getvalue() # XXX: why do we need to getvalue()? + return buf.getvalue() def build_leaderboard(