Add validator to check for overused cards
This commit is contained in:
parent
fcbc077e9a
commit
3b3962ec9a
17
ahtcg_bot.py
17
ahtcg_bot.py
|
@ -8,6 +8,7 @@ import discord
|
||||||
from discord.ext import commands, tasks
|
from discord.ext import commands, tasks
|
||||||
|
|
||||||
from arkhamdb import ArkhamDBClient, ArkhamDBDeck
|
from arkhamdb import ArkhamDBClient, ArkhamDBDeck
|
||||||
|
from validate_decks import Validator
|
||||||
from secret import TOKEN
|
from secret import TOKEN
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,16 +120,30 @@ class ArkhamDBUpdater(commands.Bot):
|
||||||
self.status_for_deck(prefix, deck)
|
self.status_for_deck(prefix, deck)
|
||||||
for prefix, deck in latest_decks.values()
|
for prefix, deck in latest_decks.values()
|
||||||
)
|
)
|
||||||
|
|
||||||
message_embed = discord.Embed(
|
message_embed = discord.Embed(
|
||||||
title=f"Updated as of {datetime.now()}", description=message_text
|
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 (
|
if (
|
||||||
last_message is not None
|
last_message is not None
|
||||||
and last_message.author.id == self.user.id
|
and last_message.author.id == self.user.id
|
||||||
and len(last_message.embeds) == 1
|
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)
|
await last_message.edit(embed=message_embed)
|
||||||
else:
|
else:
|
||||||
await channel.send(embed=message_embed)
|
await channel.send(embed=message_embed)
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
from typing import TypedDict, Optional, Union
|
from collections.abc import Iterator
|
||||||
|
from typing import TypedDict, Optional, Union, Any
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
|
||||||
ARKHAMDB_ORIGIN = "https://arkhamdb.adamgoldsmith.name"
|
ARKHAMDB_ORIGIN = "https://arkhamdb.adamgoldsmith.name"
|
||||||
|
|
||||||
|
ArkhamDBCard = Any
|
||||||
|
|
||||||
|
|
||||||
class ArkhamDBDeck(TypedDict):
|
class ArkhamDBDeck(TypedDict):
|
||||||
id: int
|
id: int
|
||||||
|
@ -42,6 +45,10 @@ class ArkhamDBClient:
|
||||||
async def close(self) -> None:
|
async def close(self) -> None:
|
||||||
await self._session.close()
|
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:
|
async def get_latest_deck(self, deck_id: int) -> ArkhamDBDeck:
|
||||||
next_deck_id = deck_id
|
next_deck_id = deck_id
|
||||||
deck = None
|
deck = None
|
||||||
|
|
|
@ -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}"'
|
Loading…
Reference in New Issue