diff --git a/ahtcg_bot.py b/ahtcg_bot.py index a7b2578..8a09755 100755 --- a/ahtcg_bot.py +++ b/ahtcg_bot.py @@ -8,6 +8,7 @@ import discord from discord.ext import commands, tasks from arkhamdb import ArkhamDBClient, ArkhamDBDeck +from validate_decks import Validator from secret import TOKEN @@ -119,16 +120,30 @@ class ArkhamDBUpdater(commands.Bot): self.status_for_deck(prefix, deck) for prefix, deck in latest_decks.values() ) + message_embed = discord.Embed( title=f"Updated as of {datetime.now()}", description=message_text ) + cards = await self.arkhamdb_client.get_cards() + validator = Validator(cards) + validation_errors = list( + validator.validate([deck for _, deck in latest_decks.values()]) + ) + if validation_errors: + message_embed.add_field( + name="Card overuse:", value="\n".join(validation_errors) + ) + if ( last_message is not None and last_message.author.id == self.user.id and len(last_message.embeds) == 1 ): - if message_text != last_message.embeds[0].description: + if ( + message_embed.description != last_message.embeds[0].description + or message_embed.fields != last_message.embeds[0].fields + ): await last_message.edit(embed=message_embed) else: await channel.send(embed=message_embed) diff --git a/arkhamdb.py b/arkhamdb.py index b53b695..1f4ead2 100644 --- a/arkhamdb.py +++ b/arkhamdb.py @@ -1,9 +1,12 @@ -from typing import TypedDict, Optional, Union +from collections.abc import Iterator +from typing import TypedDict, Optional, Union, Any import aiohttp ARKHAMDB_ORIGIN = "https://arkhamdb.adamgoldsmith.name" +ArkhamDBCard = Any + class ArkhamDBDeck(TypedDict): id: int @@ -42,6 +45,10 @@ class ArkhamDBClient: async def close(self) -> None: await self._session.close() + async def get_cards(self) -> list[ArkhamDBCard]: + async with self._session.get(self.origin + "/api/public/cards/") as resp: + return await resp.json() + async def get_latest_deck(self, deck_id: int) -> ArkhamDBDeck: next_deck_id = deck_id deck = None diff --git a/validate_decks.py b/validate_decks.py new file mode 100644 index 0000000..f8b3791 --- /dev/null +++ b/validate_decks.py @@ -0,0 +1,32 @@ +from collections import defaultdict +from collections.abc import Iterator + +from arkhamdb import ArkhamDBCard, ArkhamDBDeck + + +class Validator: + cards_by_code: dict[str, ArkhamDBCard] + + def __init__(self, cards: list[ArkhamDBCard]) -> None: + cards: list[ArkhamDBCard] + self.cards_by_code = {card["code"]: card for card in cards} + + def validate(self, decks: list[ArkhamDBDeck]) -> Iterator[str]: + card_total_counts = defaultdict(lambda: 0) + for deck in decks: + for code, count in deck["slots"].items(): + card_total_counts[code] += count + + for code, count in card_total_counts.items(): + try: + card = self.cards_by_code[code] + quantity = card["quantity"] + # assume two copies of the core set + if card["pack_code"] == "core": + quantity = quantity * 2 + + if count > quantity: + in_decks = [deck["id"] for deck in decks if code in deck["slots"]] + yield f"Too many copies of {card['name']}! ({count} > {quantity}), in decks {in_decks}" + except KeyError: + yield f'Did not find card with code "{code}"'