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]) cards.sort(key=lambda x: "Multi" if len(x.elements) > 1 else x.elements[0])
# all card face URLs # 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 # card back URL
urls.append(CARD_BACK_URL) urls.append(CARD_BACK_URL)
# multi-threaded download # multi-threaded download
images = ImageLoader.load(urls, language, num_threads) images = ImageLoader.load(urls, num_threads)
# card back Image # card back Image
back_image = images.pop(-1) back_image = images.pop(-1)

View file

@ -28,7 +28,7 @@ class Card:
self.__index = index self.__index = index
@classmethod @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: if not data:
return cls( return cls(
code=Code(""), code=Code(""),
@ -63,7 +63,10 @@ class Card:
return cls( return cls(
code=Code(data["Code"]), 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}"], name=data[f"Name_{language}"],
text=text, text=text,
) )

View file

@ -1,34 +1,17 @@
import requests
from .card import Card from .card import Card
class Cards(list[Card]): class Cards(list[Card]):
__API_URL = "https://fftcg.square-enix-games.com/de/get-cards" def __init__(self, name, cards: list[Card] = None):
if cards is None:
def __init__(self, name): cards = []
super().__init__()
super().__init__(cards)
self.__name = name self.__name = name
def __str__(self) -> str: def __str__(self) -> str:
return f"[{', '.join(str(card) for card in self)}]" 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 @property
def name(self) -> str: def name(self) -> str:
return self.__name return self.__name

View file

@ -4,7 +4,7 @@ import re
class Code: 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_PROMO = re.compile(r"(PR)-([0-9]+)")
__RE_BOSS = re.compile(r"(B)-([0-9]+)") __RE_BOSS = re.compile(r"(B)-([0-9]+)")
@ -32,7 +32,10 @@ class Code:
"?", "???", "?" "?", "???", "?"
def __str__(self) -> str: 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: def __hash__(self) -> hash:
return hash(str(self)) return hash(str(self))

View file

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

View file

@ -1,16 +1,20 @@
import logging import logging
import requests
import roman import roman
from . import Card
from .cards import Cards from .cards import Cards
from .ttsdeck import TTSDeck from .ttsdeck import TTSDeck
class Opus(Cards): 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__) logger = logging.getLogger(__name__)
params: dict[str, any]
if opus_id.isnumeric(): if opus_id.isnumeric():
name = f"Opus {opus_id}" name = f"Opus {opus_id}"
self.__number = opus_id self.__number = opus_id
@ -32,8 +36,22 @@ class Opus(Cards):
self.__filename = "?" self.__filename = "?"
params = {"set": "?"} params = {"set": "?"}
super().__init__(name) # required params:
self._load(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 # remove reprints
for card in self: for card in self:
@ -69,7 +87,10 @@ class Opus(Cards):
# simple cases: create lambdas for base elemental decks # simple cases: create lambdas for base elemental decks
base_elements = ["Fire", "Ice", "Wind", "Earth", "Lightning", "Water"] 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 |= { filters |= {
# light/darkness elemental deck # light/darkness elemental deck

View file

@ -1,5 +1,9 @@
from __future__ import annotations
import json import json
import requests
from .carddb import CardDB from .carddb import CardDB
from .cards import Cards from .cards import Cards
from .code import Code from .code import Code
@ -13,7 +17,10 @@ class TTSDeck(Cards):
# get cards from carddb # get cards from carddb
carddb = CardDB.get() 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 used
unique_face_urls = set([ unique_face_urls = set([
@ -27,6 +34,20 @@ class TTSDeck(Cards):
for i, url in enumerate(unique_face_urls) 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 @property
def tts_object(self) -> dict[str, any]: def tts_object(self) -> dict[str, any]:
# build the "CustomDeck" dictionary # build the "CustomDeck" dictionary