From 6ae0e00c2cd817a68bab25913ca8fc52574c7019 Mon Sep 17 00:00:00 2001 From: LDericher <40151420+ldericher@users.noreply.github.com> Date: Wed, 1 Sep 2021 19:01:53 +0200 Subject: [PATCH] multilanguage support (breaks upload prompt) --- fftcg/book.py | 20 +++++---------- fftcg/card.py | 65 +++++++++++++++++++++++++---------------------- fftcg/code.py | 3 +++ fftcg/language.py | 7 +++++ fftcg/opus.py | 14 +++++----- fftcg/ttsdeck.py | 40 ++++++++++++++--------------- main.py | 2 +- 7 files changed, 81 insertions(+), 70 deletions(-) diff --git a/fftcg/book.py b/fftcg/book.py index 4168205..ed032ae 100644 --- a/fftcg/book.py +++ b/fftcg/book.py @@ -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 diff --git a/fftcg/card.py b/fftcg/card.py index f58f0aa..7228cf0 100644 --- a/fftcg/card.py +++ b/fftcg/card.py @@ -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 diff --git a/fftcg/code.py b/fftcg/code.py index 91f5bd7..2fe6957 100644 --- a/fftcg/code.py +++ b/fftcg/code.py @@ -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}" diff --git a/fftcg/language.py b/fftcg/language.py index 7e303ff..4a50d26 100644 --- a/fftcg/language.py +++ b/fftcg/language.py @@ -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"] + ]) diff --git a/fftcg/opus.py b/fftcg/opus.py index 9a4c50b..444687f 100644 --- a/fftcg/opus.py +++ b/fftcg/opus.py @@ -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) diff --git a/fftcg/ttsdeck.py b/fftcg/ttsdeck.py index 140dfa1..a0672b2 100644 --- a/fftcg/ttsdeck.py +++ b/fftcg/ttsdeck.py @@ -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) diff --git a/main.py b/main.py index 7e1a74f..5e191df 100755 --- a/main.py +++ b/main.py @@ -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.")