1
0
Fork 0
mirror of https://github.com/ldericher/fftcgtool synced 2025-01-15 15:02:59 +00:00

ttsdeck import -> ffdecks

This commit is contained in:
Jörn-Michael Miehe 2021-09-13 03:50:21 +02:00
parent 8c1313da93
commit 0bfcc92191
4 changed files with 109 additions and 100 deletions

View file

@ -1,7 +1,8 @@
from .book import Book from .book import Book
from .carddb import CardDB, RWCardDB from .carddb import CardDB, RWCardDB
from .ffdecks import FFDecks
from .language import Language from .language import Language
from .opus import Opus from .opus import Opus
from .ttsdeck import TTSDeck from .ttsdeck import TTSDeck
__all__ = ["Book", "CardDB", "RWCardDB", "Language", "Opus", "TTSDeck"] __all__ = ["Book", "CardDB", "RWCardDB", "FFDecks", "Language", "Opus", "TTSDeck"]

106
fftcgtool/ffdecks.py Normal file
View file

@ -0,0 +1,106 @@
from __future__ import annotations
import logging
import re
from typing import Iterable, Iterator, Optional
import requests
from .code import Code
from .ttsdeck import TTSDeck
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)
@classmethod
def sanitized_ids(cls, deck_ids: Iterable) -> Iterator[Optional[str]]:
matches = (
cls.__RE_FFDECKS_ID.match(str(deck_id))
for deck_id in deck_ids
)
return (
match.groups()[3]
if match is not None
else None
for match in matches
)
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
codes = [
# create list of code objects
Code(card["code"])
# for each card
for card in deck_cards
# repeat to meet count
for _ in range(card["count"])
]
# create deck object
self.append(TTSDeck(codes, name, description, True))

View file

@ -168,7 +168,7 @@ def ffdecks(deck_ids: list[str]) -> list[fftcgtool.TTSDeck]:
DECK_ID: each of the Decks to import DECK_ID: each of the Decks to import
""" """
return list(fftcgtool.TTSDeck.from_ffdecks_decks(deck_ids)) return fftcgtool.FFDecks(deck_ids)
@main.result_callback() @main.result_callback()

View file

@ -3,10 +3,6 @@ from __future__ import annotations
import json import json
import logging import logging
import os import os
import re
from typing import Optional, Iterable, Iterator
import requests
from .carddb import CardDB from .carddb import CardDB
from .cards import Cards from .cards import Cards
@ -48,100 +44,6 @@ class TTSDeck(Cards):
def file_name(self) -> str: def file_name(self) -> str:
return f"{super().file_name}.json" return f"{super().file_name}.json"
__FFDECKS_API_URL = "https://ffdecks.com/api/deck"
__RE_FFDECKS_ID = re.compile(r"((https?://)?ffdecks\.com(/+api)?/+deck/+)?([0-9]+).*", flags=re.UNICODE)
@classmethod
def sanitized_ids(cls, deck_ids: Iterable) -> Iterator[Optional[str]]:
matches = (
cls.__RE_FFDECKS_ID.match(str(deck_id))
for deck_id in deck_ids
)
return (
match.groups()[3]
if match is not None
else None
for match in matches
)
@classmethod
def from_ffdecks_decks(cls, deck_ids: Iterable) -> Iterator[TTSDeck]:
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 cls.sanitized_ids(deck_ids):
if deck_id is None:
logger.error("Malformed Deck ID for FFDecks API!")
else:
# api request
res = requests.get(TTSDeck.__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
codes = [
# create list of code objects
Code(card["code"])
# for each card
for card in deck_cards
# repeat to meet count
for _ in range(card["count"])
]
# create deck object
yield cls(codes, name, description, True)
def get_tts_object(self, language: Language) -> dict[str, any]: def get_tts_object(self, language: Language) -> dict[str, any]:
carddb = CardDB() carddb = CardDB()