From 27af422ca8b17d41328a481bcc211fbc9a3989c9 Mon Sep 17 00:00:00 2001 From: LDericher <40151420+ldericher@users.noreply.github.com> Date: Tue, 14 Sep 2021 00:55:26 +0200 Subject: [PATCH] ffdecks get_deck_data --- fftcgtool/ffdecks.py | 124 +++++++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 58 deletions(-) diff --git a/fftcgtool/ffdecks.py b/fftcgtool/ffdecks.py index 4654df1..a78ce11 100644 --- a/fftcgtool/ffdecks.py +++ b/fftcgtool/ffdecks.py @@ -10,6 +10,24 @@ from .code import Code from .ttsdeck import TTSDeck +def _sort_cards_by_type(data: dict[str, str | int]) -> int: + key_prios = { + "Forward": 1, + "Summon": 2, + "Monster": 3, + "Backup": 5, + } + + try: + return key_prios[data["type"]] + except KeyError: + return 4 + + +def _sort_cards_by_cost(data: dict[str, str | int]) -> int: + return data["cost"] + + class FFDecks(list[TTSDeck]): __FFDECKS_API_URL = "https://ffdecks.com/api/deck" __RE_FFDECKS_ID = re.compile(r"((https?://)?ffdecks\.com(/+api)?/+deck/+)?([0-9]+).*", flags=re.UNICODE) @@ -28,79 +46,69 @@ class FFDecks(list[TTSDeck]): for match in matches ) + @classmethod + def get_deck_data(cls, deck_id: str) -> Optional[dict]: + logger = logging.getLogger(__name__) + + # api request + if not (res := requests.get(FFDecks.__FFDECKS_API_URL, params={"deck_id": deck_id})).ok: + logger.error(f"Invalid Deck ID '{deck_id}' for FFDecks API!") + + else: + name = f"{res.json()['name']}" + logger.info(f"Importing Deck {name!r}") + + # pre-extract usable data + card_data = [{ + "code": card["card"]["serial_number"], + "type": card["card"]["type"], + "cost": int(card["card"]["cost"]), + "count": int(card["quantity"]), + } for card in res.json()["cards"]] + + # sort cards by type, then by cost + card_data.sort(key=_sort_cards_by_cost) + card_data.sort(key=_sort_cards_by_type) + + # ffdecks quirk: some full-art promos in database + replace_full_arts = { + # line format: + # full-art-id: normal id, + "PR-051": "11-083", + "PR-055": "11-062", + } + + # replace with normal-art cards + for card in card_data: + try: + card["code"] = replace_full_arts[card["code"]] + except KeyError: + pass + + return { + "name": name, + "description": deck_id, + "cards": card_data, + } + def __init__(self, deck_ids: Iterable): super().__init__() logger = logging.getLogger(__name__) - def by_type(data: dict[str, str | int]) -> int: - key_prios = { - "Forward": 1, - "Summon": 2, - "Monster": 3, - "Backup": 5, - } - - try: - return key_prios[data["type"]] - except KeyError: - return 4 - - def by_cost(data: dict[str, str | int]) -> int: - return data["cost"] - for deck_id in self.sanitized_ids(deck_ids): if deck_id is None: logger.error("Malformed Deck ID for FFDecks API!") else: - # api request - res = requests.get(FFDecks.__FFDECKS_API_URL, params={"deck_id": deck_id}) - - if not res.ok: - logger.error(f"Invalid Deck ID '{deck_id}' for FFDecks API!") - - else: - # general metadata - name = f"{res.json()['name']}" - description = deck_id - - logger.info(f"Importing Deck {name!r}") - - # pre-extract the used data - deck_cards = [{ - "code": card["card"]["serial_number"], - "type": card["card"]["type"], - "cost": int(card["card"]["cost"]), - "count": int(card["quantity"]), - } for card in res.json()["cards"]] - - # sort cards by type, then by cost - deck_cards.sort(key=by_cost) - deck_cards.sort(key=by_type) - - # ffdecks quirk: some full-art promos in database - replace_full_arts = { - # line format: - # full-art-id: normal id, - "PR-051": "11-083", - "PR-055": "11-062", - } - - # replace with normal-art cards - for card in deck_cards: - try: - card["code"] = replace_full_arts[card["code"]] - except KeyError: - pass - + if (data := FFDecks.get_deck_data(deck_id)) is not None: codes = [ # create list of code objects Code(card["code"]) # for each card - for card in deck_cards + for card in data["cards"] # repeat to meet count for _ in range(card["count"]) ] # create deck object - self.append(TTSDeck(codes, name, description, True)) + self.append(TTSDeck(codes, data["name"], data["description"], True))