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

multilanguage support (breaks upload prompt)

This commit is contained in:
Jörn-Michael Miehe 2021-09-01 19:01:53 +02:00
parent 77bc884eb6
commit 6ae0e00c2c
7 changed files with 81 additions and 70 deletions

View file

@ -1,5 +1,6 @@
import logging
import os
from dataclasses import replace
from PIL import Image
@ -14,8 +15,8 @@ class Book:
logger = logging.getLogger(__name__)
# sort cards by element, then alphabetically
cards.sort(key=lambda x: x.name)
cards.sort(key=lambda x: "Multi" if len(x.elements) > 1 else x.elements[0])
# cards.sort(key=lambda x: x[""].name)
# cards.sort(key=lambda x: "Multi" if len(x.elements) > 1 else x.elements[0])
# all card face URLs
urls = [
@ -35,6 +36,8 @@ class Book:
for page_num, (page_images, page_cards) in enumerate(zip(
chunks(GRID.capacity, images), chunks(GRID.capacity, cards)
)):
file_name = f"{cards.file_name}_{page_num}.jpg"
# create book page Image
page_image = Image.new("RGB", GRID * RESOLUTION)
logger.info(f"New image: {page_image.size[0]}x{page_image.size[1]}")
@ -49,10 +52,11 @@ class Book:
# set card indices
for i, card in enumerate(page_cards):
card.index = i
card[language] = replace(card[language], face=file_name)
# save page
self.__pages.append({
"file_name": f"{cards.file_name}_{page_num}.jpg",
"file_name": file_name,
"image": page_image,
"cards": page_cards,
})
@ -65,13 +69,3 @@ class Book:
for page in self.__pages:
page["file_name"] = os.path.join(IMAGES_DIR_NAME, page["file_name"])
page["image"].save(page["file_name"])
# ask for upload
for page in self.__pages:
face_url = input(f"Upload '{page['file_name']}' and paste URL: ")
if not face_url:
face_url = f"file://{os.path.abspath(page['file_name'])}"
for card in page["cards"]:
card.face_url = face_url

View file

@ -1,12 +1,20 @@
from __future__ import annotations
import re
from dataclasses import dataclass
from .code import Code
from .language import Language
from .utils import encircle_symbol
@dataclass(frozen=True)
class CardContent:
name: str
text: str
face: str
class Card:
__ELEMENTS_JAP = [
"", "", "", "", "", "", "", ""
@ -21,23 +29,19 @@ class Card:
for elem_j, elem_e in zip(__ELEMENTS_JAP, __ELEMENTS_ENG)
}
def __init__(self, code: Code, elements: list[str], name: str, text: str, face_url: str = "", index: int = 0):
self.__code = code
self.__elements = elements
self.__name = name
self.__text = text
self.__face_url = face_url
def __init__(self, code: Code, elements: list[str], content: dict[Language, CardContent], index: int = 0):
self.__code: Code = code
self.__elements: list[str] = elements
self.__content: dict[Language, CardContent] = content
self.__index = index
@classmethod
def from_square_api_data(cls, data: dict[str, any], language: Language) -> Card:
def from_square_api_data(cls, data: dict[str, any]) -> Card:
if not data:
return cls(
code=Code(""),
elements=[],
name="",
text="",
content={},
)
else:
@ -69,47 +73,48 @@ class Card:
# place line breaks
return re.sub(r"\s*\[\[br]]\s*", "\n\n", text, flags=re.IGNORECASE | re.UNICODE)
content = {
language: CardContent(load_name(language), load_text(language), "")
for language in Language.all_api_langs()
}
return cls(
code=Code(data["Code"]),
elements=[
Card.__ELEMENTS_MAP[element]
for element in data["Element"].split("/")
],
name=load_name(language),
text=load_text(language),
content=content,
)
def __repr__(self) -> str:
return f"Card(code={self.code!r}, name={self.name!r}, face_url={self.face_url!r})"
return f"Card(code={self.code!r}, content={self.__content!r})"
def __str__(self) -> str:
return f"'{self.__name}' ({'/'.join(self.__elements)}, {self.code})"
if self.__content:
return f"'{self[''].name}' ({'/'.join(self.__elements)}, {self.code})"
def __getitem__(self, item: Language | str) -> CardContent:
if isinstance(item, Language):
return self.__content[item]
else:
return self.__content[Language(item)]
def __setitem__(self, key: Language | str, value: CardContent) -> None:
if isinstance(key, Language):
self.__content[key] = value
else:
self.__content[Language(key)] = value
# 6-048C
@property
def code(self) -> Code:
return self.__code
@property
def name(self) -> str:
return self.__name
@property
def text(self) -> str:
return self.__text
@property
def elements(self) -> list[str]:
return self.__elements
@property
def face_url(self) -> str:
return self.__face_url
@face_url.setter
def face_url(self, face_url: str) -> None:
self.__face_url = face_url
@property
def index(self) -> int:
return self.__index

View file

@ -30,6 +30,9 @@ class Code:
object.__setattr__(self, "serial", serial)
object.__setattr__(self, "rarity", rarity)
def __str__(self) -> str:
return self.long
@property
def short(self) -> str:
return f"{self.opus}-{self.serial:03}"

View file

@ -35,3 +35,10 @@ class Language:
return ""
else:
return "_EN"
@classmethod
def all_api_langs(cls) -> set[Language]:
return set([
cls(short)
for short in ["de", "en", "es", "fr", "it", "ja"]
])

View file

@ -49,15 +49,17 @@ class Opus(Cards):
# get cards from square api
req = requests.post(Opus.__SQUARE_API_URL, json=params)
super().__init__(name, [
Card.from_square_api_data(card_data, language)
cards = [
Card.from_square_api_data(card_data)
for card_data in req.json()["cards"]
])
]
# remove reprints
for card in self:
if not card.code.opus == self.__number:
self.remove(card)
super().__init__(name, [
card
for card in cards
if card.code.opus == self.__number
])
# sort cards by opus, then serial
self.sort(key=lambda x: x.code.serial)

View file

@ -8,6 +8,7 @@ import requests
from .carddb import CardDB
from .cards import Cards
from .code import Code
from .language import Language
from .utils import CARD_BACK_URL, DECKS_DIR_NAME
@ -23,18 +24,6 @@ class TTSDeck(Cards):
for code in codes
])
# unique face urls used
unique_face_urls = set([
card.face_url
for card in self
])
# lookup for indices of urls
self.__url_indices = {
url: i + 1
for i, url in enumerate(unique_face_urls)
}
__FFDECKS_API_URL = "https://ffdecks.com/api/deck"
@classmethod
@ -49,8 +38,19 @@ class TTSDeck(Cards):
return cls(codes, name, description)
@property
def tts_object(self) -> dict[str, any]:
def tts_object(self, language: Language) -> dict[str, any]:
# unique face urls used
unique_faces = set([
card[language].face
for card in self
])
# lookup for indices of urls
url_indices = {
url: i + 1
for i, url in enumerate(unique_faces)
}
# build the "CustomDeck" dictionary
custom_deck = {
str(i): {
@ -58,7 +58,7 @@ class TTSDeck(Cards):
"NumHeight": "7",
"FaceURL": url,
"BackURL": CARD_BACK_URL,
} for url, i in self.__url_indices.items()
} for url, i in url_indices.items()
}
# values both in main deck and each contained card
@ -81,9 +81,9 @@ class TTSDeck(Cards):
# cards contained in deck
contained_objects = [
{
"Nickname": card.name,
"Description": card.text,
"CardID": 100 * self.__url_indices[card.face_url] + card.index,
"Nickname": card[language].name,
"Description": card[language].text,
"CardID": 100 * url_indices[card[language].face] + card.index,
"Name": "Card",
"Hands": True,
@ -112,11 +112,11 @@ class TTSDeck(Cards):
} | common_dict
]}
def save(self) -> None:
def save(self, language: Language) -> None:
# only save if the deck contains cards
if self:
if not os.path.exists(DECKS_DIR_NAME):
os.mkdir(DECKS_DIR_NAME)
with open(os.path.join(DECKS_DIR_NAME, f"{self.file_name}.json"), "w") as file:
json.dump(self.tts_object, file, indent=2)
json.dump(self.tts_object(language), file, indent=2)

View file

@ -143,7 +143,7 @@ def main() -> None:
# call function based on args
for deck in args.func(args):
deck.save()
deck.save(args.language)
# bye
print("Done. Put the generated JSON files in your 'Saved Objects' Folder.")