mirror of
https://github.com/ldericher/fftcgtool
synced 2025-01-15 15:02:59 +00:00
cleanup
This commit is contained in:
parent
8360eb69b2
commit
81122f8de8
7 changed files with 68 additions and 56 deletions
|
@ -5,7 +5,7 @@ from PIL import Image
|
||||||
|
|
||||||
from .cards import Cards
|
from .cards import Cards
|
||||||
from .imageloader import ImageLoader
|
from .imageloader import ImageLoader
|
||||||
from .utils import GRID, RESOLUTION, BOOK_YML_NAME
|
from .utils import GRID, RESOLUTION, BOOK_YML_NAME, CARD_BACK_URL
|
||||||
|
|
||||||
|
|
||||||
class Book:
|
class Book:
|
||||||
|
@ -18,10 +18,8 @@ class Book:
|
||||||
|
|
||||||
# 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 (image by Aurik)
|
# card back URL
|
||||||
urls.append(
|
urls.append(CARD_BACK_URL)
|
||||||
"http://cloud-3.steamusercontent.com/ugc/948455238665576576/85063172B8C340602E8D6C783A457122F53F7843/"
|
|
||||||
)
|
|
||||||
|
|
||||||
# multi-threaded download
|
# multi-threaded download
|
||||||
images = ImageLoader.load(urls, language, num_threads)
|
images = ImageLoader.load(urls, language, num_threads)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import json
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
@ -23,8 +22,6 @@ class Card(yaml.YAMLObject):
|
||||||
"闇": "Darkness"
|
"闇": "Darkness"
|
||||||
}
|
}
|
||||||
|
|
||||||
__ELEMENTS = "".join(__ELEMENTS_MAP.keys())
|
|
||||||
|
|
||||||
def __init__(self, code, elements, name, text):
|
def __init__(self, code, elements, name, text):
|
||||||
self.__code = code
|
self.__code = code
|
||||||
self.__elements = elements
|
self.__elements = elements
|
||||||
|
@ -55,15 +52,15 @@ class Card(yaml.YAMLObject):
|
||||||
# place other letter and numerical cost symbols
|
# place other letter and numerical cost symbols
|
||||||
text = re.sub(r"《([a-z0-9])》", sub_encircle, text, flags=re.IGNORECASE)
|
text = re.sub(r"《([a-z0-9])》", sub_encircle, text, flags=re.IGNORECASE)
|
||||||
# place elemental cost symbols
|
# place elemental cost symbols
|
||||||
text = re.sub(rf"《([{Card.__ELEMENTS}])》", sub_elements, text, flags=re.IGNORECASE)
|
text = re.sub(rf"《([{''.join(Card.__ELEMENTS_MAP.keys())}])》", sub_elements, text, flags=re.IGNORECASE)
|
||||||
# place dull symbols
|
# place dull symbols
|
||||||
text = text.replace("《ダル》", "[⤵]")
|
text = text.replace("《ダル》", "[⤵]")
|
||||||
# replace formatting hints with brackets
|
# replace formatting hints with brackets
|
||||||
text = re.sub(r"\[\[[a-z]\]\]([^\[]*?)\s*\[\[/\]\]\s*", r"[\1] ", text, flags=re.IGNORECASE)
|
text = re.sub(r"\[\[[a-z]]]([^\[]*?)\s*\[\[/]]\s*", r"[\1] ", text, flags=re.IGNORECASE)
|
||||||
# place EX-BURST markers
|
# place EX-BURST markers
|
||||||
text = re.sub(r"\[\[ex\]\]\s*EX BURST\s*\[\[/\]\]\s*", r"[EX BURST] ", text, flags=re.IGNORECASE)
|
text = re.sub(r"\[\[ex]]\s*EX BURST\s*\[\[/]]\s*", r"[EX BURST] ", text, flags=re.IGNORECASE)
|
||||||
# place line breaks
|
# place line breaks
|
||||||
text = re.sub(r"\s*\[\[br\]\]\s*", "\n\n", text, flags=re.IGNORECASE)
|
text = re.sub(r"\s*\[\[br]]\s*", "\n\n", text, flags=re.IGNORECASE)
|
||||||
|
|
||||||
return cls(
|
return cls(
|
||||||
code=Code(data["Code"]),
|
code=Code(data["Code"]),
|
||||||
|
@ -75,9 +72,6 @@ class Card(yaml.YAMLObject):
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"'{self.__name}' ({'/'.join(self.__elements)}, {self.code})"
|
return f"'{self.__name}' ({'/'.join(self.__elements)}, {self.code})"
|
||||||
|
|
||||||
def to_json(self) -> str:
|
|
||||||
return json.dumps(self, default=lambda o: o.__dict__)
|
|
||||||
|
|
||||||
# 6-048C
|
# 6-048C
|
||||||
@property
|
@property
|
||||||
def code(self) -> Code:
|
def code(self) -> Code:
|
||||||
|
|
|
@ -6,6 +6,22 @@ from .card import Card
|
||||||
class Cards(list[Card]):
|
class Cards(list[Card]):
|
||||||
__API_URL = "https://fftcg.square-enix-games.com/de/get-cards"
|
__API_URL = "https://fftcg.square-enix-games.com/de/get-cards"
|
||||||
|
|
||||||
|
def __init__(self, name):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.__name = name
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return f"[{', '.join(str(card) for card in self)}]"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self) -> str:
|
||||||
|
return self.__name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def file_name(self) -> str:
|
||||||
|
return self.name.lower().replace(" ", "_")
|
||||||
|
|
||||||
def _load(self, params: dict[str, any]):
|
def _load(self, params: dict[str, any]):
|
||||||
# required params:
|
# required params:
|
||||||
# text
|
# text
|
||||||
|
@ -20,6 +36,3 @@ class Cards(list[Card]):
|
||||||
req = requests.post(Cards.__API_URL, json=params)
|
req = requests.post(Cards.__API_URL, json=params)
|
||||||
self.clear()
|
self.clear()
|
||||||
self.extend([Card.from_data(card_data, "EN") for card_data in req.json()["cards"]])
|
self.extend([Card.from_data(card_data, "EN") for card_data in req.json()["cards"]])
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
return "\n".join(str(card) for card in self)
|
|
||||||
|
|
|
@ -8,34 +8,31 @@ from .ttsdeck import TTSDeck
|
||||||
|
|
||||||
class Opus(Cards):
|
class Opus(Cards):
|
||||||
def __init__(self, opus_id: str):
|
def __init__(self, opus_id: str):
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
if opus_id.isnumeric():
|
if opus_id.isnumeric():
|
||||||
self.__name = f"Opus {roman.toRoman(int(opus_id)).upper()}"
|
name = f"Opus {opus_id}"
|
||||||
self.__number = opus_id
|
self.__number = opus_id
|
||||||
self.__filename = f"opus_{opus_id}"
|
params = {"set": [f"Opus {roman.toRoman(int(opus_id)).upper()}"]}
|
||||||
params = {"set": [self.__name]}
|
|
||||||
|
|
||||||
elif opus_id == "chaos":
|
elif opus_id == "chaos":
|
||||||
self.__name = "Boss Deck Chaos"
|
name = "Boss Deck Chaos"
|
||||||
self.__number = "B"
|
self.__number = "B"
|
||||||
self.__filename = "boss_deck_chaos"
|
params = {"set": [name]}
|
||||||
params = {"set": [self.__name]}
|
|
||||||
|
|
||||||
elif opus_id == "promo":
|
elif opus_id == "promo":
|
||||||
self.__name = "Promo"
|
name = "Promo"
|
||||||
self.__number = "PR"
|
self.__number = "PR"
|
||||||
self.__filename = "promo"
|
|
||||||
params = {"rarity": ["pr"]}
|
params = {"rarity": ["pr"]}
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.__name = "?"
|
name = "?"
|
||||||
self.__number = "?"
|
self.__number = "?"
|
||||||
self.__filename = "?"
|
self.__filename = "?"
|
||||||
params = {"set": "?"}
|
params = {"set": "?"}
|
||||||
|
|
||||||
|
super().__init__(name)
|
||||||
self._load(params)
|
self._load(params)
|
||||||
|
|
||||||
# remove reprints
|
# remove reprints
|
||||||
|
@ -50,25 +47,21 @@ class Opus(Cards):
|
||||||
for card in self:
|
for card in self:
|
||||||
logger.info(f"imported card {card}")
|
logger.info(f"imported card {card}")
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self) -> str:
|
|
||||||
return self.__name
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def number(self) -> str:
|
def number(self) -> str:
|
||||||
return self.__number
|
return self.__number
|
||||||
|
|
||||||
@property
|
|
||||||
def filename(self) -> str:
|
|
||||||
return self.__filename
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def elemental_decks(self) -> list[TTSDeck]:
|
def elemental_decks(self) -> list[TTSDeck]:
|
||||||
if self.name in ["Promo", "Boss Deck Chaos"]:
|
if self.name in ["Promo", "Boss Deck Chaos"]:
|
||||||
return [TTSDeck([
|
return [TTSDeck(
|
||||||
card.code
|
[
|
||||||
for card in self
|
card.code
|
||||||
])]
|
for card in self
|
||||||
|
],
|
||||||
|
f"{self.name}",
|
||||||
|
f"All {self.name} Cards in elemental, then alphabetical order"
|
||||||
|
)]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
def element_filter(element: str):
|
def element_filter(element: str):
|
||||||
|
@ -76,17 +69,21 @@ 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 = [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
|
||||||
lambda card: card.elements == ["Light"] or card.elements == ["Darkness"],
|
"Light/Darkness": lambda card: card.elements == ["Light"] or card.elements == ["Darkness"],
|
||||||
# multi element deck
|
# multi element deck
|
||||||
lambda card: len(card.elements) > 1,
|
"Multi": lambda card: len(card.elements) > 1,
|
||||||
]
|
}
|
||||||
|
|
||||||
return [TTSDeck([
|
return [TTSDeck(
|
||||||
card.code
|
[
|
||||||
for card in self
|
card.code
|
||||||
if f(card)
|
for card in self
|
||||||
]) for f in filters]
|
if f(card)
|
||||||
|
],
|
||||||
|
f"{self.name} {elem}",
|
||||||
|
f"All {self.name} Cards with {elem} element in alphabetical order"
|
||||||
|
) for elem, f in filters.items()]
|
||||||
|
|
|
@ -2,13 +2,17 @@ import json
|
||||||
|
|
||||||
from .carddb import CardDB
|
from .carddb import CardDB
|
||||||
from .code import Code
|
from .code import Code
|
||||||
|
from .utils import CARD_BACK_URL
|
||||||
|
|
||||||
|
|
||||||
class TTSDeck(list[dict[str, any]]):
|
class TTSDeck(list[dict[str, any]]):
|
||||||
def __init__(self, codes: list[Code]):
|
def __init__(self, codes: list[Code], name: str, description: str):
|
||||||
carddb = CardDB.get()
|
carddb = CardDB.get()
|
||||||
super().__init__([carddb[code] for code in codes])
|
super().__init__([carddb[code] for code in codes])
|
||||||
|
|
||||||
|
self.__name = name
|
||||||
|
self.__description = description
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
face_urls = list(set([entry["file"] for entry in self]))
|
face_urls = list(set([entry["file"] for entry in self]))
|
||||||
|
|
||||||
|
@ -17,7 +21,7 @@ class TTSDeck(list[dict[str, any]]):
|
||||||
"NumWidth": "10",
|
"NumWidth": "10",
|
||||||
"NumHeight": "7",
|
"NumHeight": "7",
|
||||||
"FaceURL": url,
|
"FaceURL": url,
|
||||||
"BackURL": "http://cloud-3.steamusercontent.com/ugc/948455238665576576/85063172B8C340602E8D6C783A457122F53F7843/",
|
"BackURL": CARD_BACK_URL,
|
||||||
} for i, url in enumerate(face_urls)
|
} for i, url in enumerate(face_urls)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,8 +67,8 @@ class TTSDeck(list[dict[str, any]]):
|
||||||
jsondict = {"ObjectStates": [
|
jsondict = {"ObjectStates": [
|
||||||
{
|
{
|
||||||
"Name": "Deck",
|
"Name": "Deck",
|
||||||
"Nickname": "TODO Deck Name",
|
"Nickname": self.__name,
|
||||||
"Description": "TODO Deck Description",
|
"Description": self.__description,
|
||||||
|
|
||||||
"Hands": False,
|
"Hands": False,
|
||||||
"SidewaysCard": False,
|
"SidewaysCard": False,
|
||||||
|
@ -76,3 +80,6 @@ class TTSDeck(list[dict[str, any]]):
|
||||||
]}
|
]}
|
||||||
|
|
||||||
return json.dumps(jsondict, indent=2)
|
return json.dumps(jsondict, indent=2)
|
||||||
|
|
||||||
|
def save(self, file_name: str) -> None:
|
||||||
|
pass
|
||||||
|
|
|
@ -4,6 +4,8 @@ from .grid import Grid
|
||||||
GRID = Grid((10, 7)) # default in TTsim: 10 columns, 7 rows
|
GRID = Grid((10, 7)) # default in TTsim: 10 columns, 7 rows
|
||||||
RESOLUTION = Grid((429, 600)) # default in TTsim: 480x670 pixels per card
|
RESOLUTION = Grid((429, 600)) # default in TTsim: 480x670 pixels per card
|
||||||
BOOK_YML_NAME = "book.yml"
|
BOOK_YML_NAME = "book.yml"
|
||||||
|
# card back URL (image by Aurik)
|
||||||
|
CARD_BACK_URL = "http://cloud-3.steamusercontent.com/ugc/948455238665576576/85063172B8C340602E8D6C783A457122F53F7843/"
|
||||||
|
|
||||||
|
|
||||||
# functions
|
# functions
|
||||||
|
|
5
main.py
5
main.py
|
@ -41,12 +41,13 @@ def main() -> None:
|
||||||
# main program
|
# main program
|
||||||
opus = fftcg.Opus(args.opus_id)
|
opus = fftcg.Opus(args.opus_id)
|
||||||
book = fftcg.Book(opus, "eg", args.num_threads)
|
book = fftcg.Book(opus, "eg", args.num_threads)
|
||||||
book.save(opus.filename)
|
book.save(opus.file_name)
|
||||||
|
|
||||||
# create elemental decks for opus
|
# load the current carddb
|
||||||
carddb = fftcg.CardDB.get()
|
carddb = fftcg.CardDB.get()
|
||||||
carddb.load()
|
carddb.load()
|
||||||
|
|
||||||
|
# create elemental decks for opus
|
||||||
for deck in opus.elemental_decks:
|
for deck in opus.elemental_decks:
|
||||||
print(deck)
|
print(deck)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue