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

inverted book.yml; card text formatting

This commit is contained in:
Jörn-Michael Miehe 2021-08-16 13:17:24 +02:00
parent eed07e4bb0
commit 2946bc81e4
5 changed files with 140 additions and 61 deletions

View file

@ -4,6 +4,7 @@ import yaml
from PIL import Image from PIL import Image
from .cards import Cards from .cards import Cards
from .code import Code
from .grid import Grid from .grid import Grid
from .imageloader import ImageLoader from .imageloader import ImageLoader
@ -55,24 +56,39 @@ class Book:
return self.__pages[index]["image"] return self.__pages[index]["image"]
def save(self, filename: str) -> None: def save(self, filename: str) -> None:
pages: dict[str, dict[str, any]] book: dict[str, dict[str, any]]
# load pages.yml file # load book.yml file
try: try:
with open("pages.yml", "r") as file: with open("book.yml", "r") as file:
pages = yaml.load(file, Loader=yaml.Loader) book = yaml.load(file, Loader=yaml.Loader)
except FileNotFoundError: except FileNotFoundError:
pages = {} book = {}
# save book # save book
for i, page in enumerate(self.__pages): for i, page in enumerate(self.__pages):
fn = f"{filename}_{i}.jpg" fn = f"{filename}_{i}.jpg"
# save page image # save page image
page["image"].save(fn) page["image"].save(fn)
# add contents of image # add contents of that image
pages[fn] = {} book[fn] = {"cards": page["cards"]}
pages[fn]["cards"] = page["cards"]
# update pages.yml file # update book.yml file
with open("pages.yml", "w") as file: with open("book.yml", "w") as file:
yaml.dump(pages, file, Dumper=yaml.Dumper) yaml.dump(book, file, Dumper=yaml.Dumper)
# invert book
inverse_book: dict[Code, dict[str, any]] = {}
for fn, content in book.items():
inverse_book |= {
str(card.code): {
"card": card,
"file": fn,
"index": i
} for i, card in enumerate(content["cards"])
}
# write inverse_book.yml file
with open("inverse_book.yml", "w") as file:
yaml.dump(inverse_book, file, Dumper=yaml.Dumper)

View file

@ -3,6 +3,32 @@ import re
import yaml import yaml
from .code import Code
def encircle_symbol(symbol: str, negative: bool):
symbol = symbol[0].upper()
base_symbols: tuple[str, str] = "", ""
if symbol.isalpha():
if negative:
base_symbols = "A", "🅐"
else:
base_symbols = "A", ""
elif symbol == "0":
if negative:
base_symbols = "0", "🄌"
else:
base_symbols = "0", ""
elif symbol.isnumeric():
if negative:
base_symbols = "1", ""
else:
base_symbols = "1", ""
symbol_num = ord(symbol) - ord(base_symbols[0])
return chr(ord(base_symbols[1]) + symbol_num)
class Card(yaml.YAMLObject): class Card(yaml.YAMLObject):
yaml_tag = u'!Card' yaml_tag = u'!Card'
@ -18,10 +44,10 @@ class Card(yaml.YAMLObject):
"": "Darkness" "": "Darkness"
} }
def __init__(self, opus, serial, rarity, elements, name, text): __ELEMENTS = "".join(__ELEMENTS_MAP.keys())
self.__opus = opus
self.__serial = serial def __init__(self, code, elements, name, text):
self.__rarity = rarity self.__code = code
self.__elements = elements self.__elements = elements
self.__name = name self.__name = name
self.__text = text self.__text = text
@ -30,44 +56,41 @@ class Card(yaml.YAMLObject):
def from_data(cls, data: dict[str, any], language: str): def from_data(cls, data: dict[str, any], language: str):
if not data: if not data:
return cls( return cls(
opus="0", code=Code(""),
serial="000",
rarity="X",
elements=[], elements=[],
name=None, name=None,
text=None, text=None,
) )
else: else:
if str(data["Code"])[0].isnumeric(): def sub_encircle(match: re.Match):
# card code starts with a number return encircle_symbol(match.group(1), True)
opus, serial, rarity = \
re.match(r"([0-9]+)-([0-9]+)([CRHLS])", data["Code"]).groups()
elif str(data["Code"]).startswith("PR"): def sub_elements(match: re.Match):
# card code starts with "PR" return encircle_symbol(Card.__ELEMENTS_MAP[match.group(1)], True)
opus, serial = \
re.match(r"(PR)-([0-9]+)", data["Code"]).groups()
rarity = ""
elif str(data["Code"]).startswith("B"): # load text
# card code starts with "B" text = str(data[f"Text_{language}"])
opus, serial = \ # place "S" symbols
re.match(r"(B)-([0-9]+)", data["Code"]).groups() text = text.replace("《S》", encircle_symbol("S", False))
rarity = "" # place other letter and numerical cost symbols
text = re.sub(r"《([a-z0-9])》", sub_encircle, text, flags=re.IGNORECASE)
else: # place elemental cost symbols
# card code not recognized text = re.sub(rf"《([{Card.__ELEMENTS}])》", sub_elements, text, flags=re.IGNORECASE)
opus, serial, rarity = \ # place dull symbols
"?", "???", "?" text = text.replace("《ダル》", "[⤵]")
# replace formatting hints with brackets
text = re.sub(r"\[\[[a-z]\]\]([^\[]*?)\s*\[\[/\]\]\s*", r"[\1] ", text, flags=re.IGNORECASE)
# place EX-BURST markers
text = re.sub(r"\[\[ex\]\]\s*EX BURST\s*\[\[/\]\]\s*", r"[EX BURST] ", text, flags=re.IGNORECASE)
# place line breaks
text = re.sub(r"\s*\[\[br\]\]\s*", "\n\n", text, flags=re.IGNORECASE)
return cls( return cls(
opus=opus, code=Code(data["Code"]),
serial=serial,
rarity=rarity,
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=data[f"Text_{language}"], text=text,
) )
def __str__(self) -> str: def __str__(self) -> str:
@ -78,20 +101,8 @@ class Card(yaml.YAMLObject):
# 6-048C # 6-048C
@property @property
def code(self) -> str: def code(self) -> Code:
return f"{self.__opus}-{self.__serial}{self.__rarity}" return self.__code
@property
def opus(self) -> str:
return self.__opus
@property
def serial(self) -> int:
return int(self.__serial)
@property
def rarity(self) -> str:
return self.__rarity
@property @property
def name(self) -> str: def name(self) -> str:

View file

@ -6,7 +6,7 @@ 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, params: dict[str, any]): def _load(self, params: dict[str, any]):
# required params: # required params:
# text # text
# supported params: # supported params:
@ -18,7 +18,8 @@ class Cards(list[Card]):
params["text"] = "" params["text"] = ""
req = requests.post(Cards.__API_URL, json=params) req = requests.post(Cards.__API_URL, json=params)
super().__init__([Card.from_data(card_data, "EN") for card_data in req.json()["cards"]]) self.clear()
self.extend([Card.from_data(card_data, "EN") for card_data in req.json()["cards"]])
def __str__(self) -> str: def __str__(self) -> str:
return "\n".join(str(card) for card in self) return "\n".join(str(card) for card in self)

49
fftcg/code.py Normal file
View file

@ -0,0 +1,49 @@
import re
import yaml
class Code(yaml.YAMLObject):
yaml_tag = u'!Code'
__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]+)")
def __init__(self, code: str):
if code[0].isnumeric():
# card code starts with a number
self.__opus, self.__serial, self.__rarity = \
Code.__RE_NUM.match(code).groups()
elif code.startswith("PR"):
# card code starts with "PR"
self.__opus, self.__serial = \
Code.__RE_PROMO.match(code).groups()
self.__rarity = ""
elif code.startswith("B"):
# card code starts with "B"
self.__opus, self.__serial = \
Code.__RE_BOSS.match(code).groups()
self.__rarity = ""
else:
# card code not recognized
self.__opus, self.__serial, self.__rarity = \
"?", "???", "?"
def __str__(self) -> str:
return f"{self.__opus}-{self.__serial}{self.__rarity}"
@property
def opus(self) -> str:
return self.__opus
@property
def serial(self) -> int:
return int(self.__serial)
@property
def rarity(self) -> str:
return self.__rarity

View file

@ -7,6 +7,8 @@ from .cards import Cards
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():
@ -33,16 +35,16 @@ class Opus(Cards):
self.__filename = "?" self.__filename = "?"
params = {"set": "?"} params = {"set": "?"}
super().__init__(params) self._load(params)
# remove reprints # remove reprints
for card in self: for card in self:
if not card.code.startswith(self.__number + "-"): if not card.code.opus == self.__number:
self.remove(card) self.remove(card)
# sort cards by opus, then serial # sort cards by opus, then serial
self.sort(key=lambda x: x.serial) self.sort(key=lambda x: x.code.serial)
self.sort(key=lambda x: x.opus) self.sort(key=lambda x: x.code.opus)
for card in self: for card in self:
logger.info(f"imported card {card}") logger.info(f"imported card {card}")