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

cleanup, FFDECKS query

This commit is contained in:
Jörn-Michael Miehe 2021-08-21 00:16:38 +02:00
parent cb7b8c0620
commit 06d83af5c1
7 changed files with 74 additions and 39 deletions

View file

@ -17,12 +17,15 @@ class Book:
cards.sort(key=lambda x: "Multi" if len(x.elements) > 1 else x.elements[0])
# all card face URLs
urls = [f"https://fftcg.cdn.sewest.net/images/cards/full/{card.code}_{language}.jpg" for card in cards]
urls = [
f"https://fftcg.cdn.sewest.net/images/cards/full/{card.code}_{language}.jpg"
for card in cards
]
# card back URL
urls.append(CARD_BACK_URL)
# multi-threaded download
images = ImageLoader.load(urls, language, num_threads)
images = ImageLoader.load(urls, num_threads)
# card back Image
back_image = images.pop(-1)

View file

@ -28,7 +28,7 @@ class Card:
self.__index = index
@classmethod
def from_data(cls, data: dict[str, any], language: str) -> Card:
def from_square_api_data(cls, data: dict[str, any], language: str) -> Card:
if not data:
return cls(
code=Code(""),
@ -63,7 +63,10 @@ class Card:
return cls(
code=Code(data["Code"]),
elements=[Card.__ELEMENTS_MAP[element] for element in data["Element"].split("/")],
elements=[
Card.__ELEMENTS_MAP[element]
for element in data["Element"].split("/")
],
name=data[f"Name_{language}"],
text=text,
)

View file

@ -1,34 +1,17 @@
import requests
from .card import Card
class Cards(list[Card]):
__API_URL = "https://fftcg.square-enix-games.com/de/get-cards"
def __init__(self, name):
super().__init__()
def __init__(self, name, cards: list[Card] = None):
if cards is None:
cards = []
super().__init__(cards)
self.__name = name
def __str__(self) -> str:
return f"[{', '.join(str(card) for card in self)}]"
def _load(self, params: dict[str, any]) -> None:
# required params:
# text
# supported params:
# [str] text, language, code, multicard="○"|"", ex_burst="○"|"", special="《S》"|""
# [array] type, element, cost, rarity, power, category_1, set
# [int] exactmatch=0|1
if "text" not in params:
params["text"] = ""
req = requests.post(Cards.__API_URL, json=params)
self.clear()
self.extend([Card.from_data(card_data, "EN") for card_data in req.json()["cards"]])
@property
def name(self) -> str:
return self.__name

View file

@ -4,7 +4,7 @@ import re
class Code:
__RE_NUM = re.compile(r"([0-9]+)-([0-9]+)([CRHLS])")
__RE_NUM = re.compile(r"([0-9]+)-([0-9]+)([CRHLS]?)")
__RE_PROMO = re.compile(r"(PR)-([0-9]+)")
__RE_BOSS = re.compile(r"(B)-([0-9]+)")
@ -32,7 +32,10 @@ class Code:
"?", "???", "?"
def __str__(self) -> str:
return f"{self.__opus}-{self.__serial}{self.__rarity}"
return f"{self.__opus}-{self.__serial}"
def __repr__(self) -> str:
return f"Code(\"{self.__opus}-{self.__serial}{self.__rarity}\")"
def __hash__(self) -> hash:
return hash(str(self))

View file

@ -10,12 +10,10 @@ from fftcg.utils import RESOLUTION
class ImageLoader(threading.Thread):
def __init__(self, url_queue: queue.Queue, resolution: tuple[int, int], language: str):
def __init__(self, url_queue: queue.Queue):
super().__init__()
self.__queue = url_queue
self.__resolution = resolution
self.__language = language
self.__images = {}
def run(self) -> None:
@ -34,7 +32,7 @@ class ImageLoader(threading.Thread):
# unify images
image.convert("RGB")
image = image.resize(self.__resolution, Image.BICUBIC)
image = image.resize(RESOLUTION, Image.BICUBIC)
break
except requests.exceptions.RequestException:
pass
@ -46,14 +44,14 @@ class ImageLoader(threading.Thread):
self.__queue.task_done()
@classmethod
def load(cls, urls: list[str], language: str, num_threads: int) -> list[Image.Image]:
def load(cls, urls: list[str], num_threads: int) -> list[Image.Image]:
url_queue = queue.Queue()
for url in urls:
url_queue.put(url)
loaders = []
for _ in range(num_threads):
loader = cls(url_queue, RESOLUTION, language)
loader = cls(url_queue)
loaders.append(loader)
loader.start()
@ -65,7 +63,10 @@ class ImageLoader(threading.Thread):
images |= loader.images
# sort images to match the initial "urls" list
images = [images[url] for url in urls]
images = [
images[url]
for url in urls
]
return images

View file

@ -1,16 +1,20 @@
import logging
import requests
import roman
from . import Card
from .cards import Cards
from .ttsdeck import TTSDeck
class Opus(Cards):
def __init__(self, opus_id: str):
__SQUARE_API_URL = "https://fftcg.square-enix-games.com/de/get-cards"
def __init__(self, opus_id: str):
logger = logging.getLogger(__name__)
params: dict[str, any]
if opus_id.isnumeric():
name = f"Opus {opus_id}"
self.__number = opus_id
@ -32,8 +36,22 @@ class Opus(Cards):
self.__filename = "?"
params = {"set": "?"}
super().__init__(name)
self._load(params)
# required params:
# text
# supported params:
# [str] text, language, code, multicard="○"|"", ex_burst="○"|"", special="《S》"|""
# [array] type, element, cost, rarity, power, category_1, set
# [int] exactmatch=0|1
if "text" not in params:
params["text"] = ""
# get cards from square api
req = requests.post(Opus.__SQUARE_API_URL, json=params)
super().__init__(name, [
Card.from_square_api_data(card_data, "EN")
for card_data in req.json()["cards"]
])
# remove reprints
for card in self:
@ -69,7 +87,10 @@ class Opus(Cards):
# simple cases: create lambdas for base elemental decks
base_elements = ["Fire", "Ice", "Wind", "Earth", "Lightning", "Water"]
filters = {elem: element_filter(elem) for elem in base_elements}
filters = {
elem: element_filter(elem)
for elem in base_elements
}
filters |= {
# light/darkness elemental deck

View file

@ -1,5 +1,9 @@
from __future__ import annotations
import json
import requests
from .carddb import CardDB
from .cards import Cards
from .code import Code
@ -13,7 +17,10 @@ class TTSDeck(Cards):
# get cards from carddb
carddb = CardDB.get()
self.extend([carddb[code] for code in codes])
self.extend([
carddb[code]
for code in codes
])
# unique face urls used
unique_face_urls = set([
@ -27,6 +34,20 @@ class TTSDeck(Cards):
for i, url in enumerate(unique_face_urls)
}
__FFDECKS_API_URL = "https://ffdecks.com/api/deck"
@classmethod
def from_ffdecks_deck(cls, deck_id: str) -> TTSDeck:
req = requests.get(TTSDeck.__FFDECKS_API_URL, params={"deck_id": deck_id})
codes = [
Code(card["card"]["serial_number"])
for card in req.json()["cards"]
]
name = req.json()["name"]
description = req.json()["description"]
return cls(codes, name, description)
@property
def tts_object(self) -> dict[str, any]:
# build the "CustomDeck" dictionary