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

fallback for nonexistent images, verbosity, logging output

This commit is contained in:
Jörn-Michael Miehe 2021-08-24 17:29:12 +02:00
parent ba58a99690
commit 0f6c7be504
5 changed files with 60 additions and 21 deletions

View file

@ -19,11 +19,11 @@ class Book:
# all card face URLs
urls = [
f"https://fftcg.cdn.sewest.net/images/cards/full/{card.code}_{language.image_suffix}.jpg"
("https://fftcg.cdn.sewest.net/images/cards/full/{}_{}.jpg", str(card.code), language.image_suffix)
for card in cards
]
# card back URL
urls.append(CARD_BACK_URL)
urls.append((CARD_BACK_URL, "", ""))
# multi-threaded download
images = ImageLoader.load(urls, num_threads)

View file

@ -1,33 +1,46 @@
import io
import logging
import multiprocessing
import requests
from PIL import Image
from .language import Language
from .utils import RESOLUTION
# constants
FALLBACK_LANGUAGE = Language("en")
class ImageLoader:
@classmethod
def _load(cls, url: str) -> Image.Image:
def _load_inner(cls, url_parts: tuple[str, str, str]) -> Image.Image:
logger = logging.getLogger(__name__)
base_url, code, lang_suffix = url_parts
# put together image url
url = base_url.format(code, lang_suffix)
logger.info(f"trying image {url}")
# fetch image (retry on fail)
while True:
logger.info(f"downloading image {url}")
try:
res = requests.get(url)
image = Image.open(io.BytesIO(res.content))
res = requests.get(url, stream=True)
break
except requests.RequestException:
pass
# if rejected, substitute the english version
if not res.status_code == 200:
logger.warning(f"falling back to english version of {url}")
return cls._load_inner((base_url, code, FALLBACK_LANGUAGE.image_suffix))
# unify images
image = Image.open(res.raw)
image.convert(mode="RGB")
return image.resize(RESOLUTION, Image.BICUBIC)
except requests.exceptions.RequestException:
pass
@classmethod
def load(cls, urls: list[str], num_threads: int) -> list[Image.Image]:
def load(cls, urls_parts: list[tuple[str, str, str]], num_threads: int) -> list[Image.Image]:
with multiprocessing.Pool(num_threads) as p:
return p.map(ImageLoader._load, urls)
return p.map(cls._load_inner, urls_parts)

View file

@ -1,3 +1,6 @@
from __future__ import annotations
class Language:
def __init__(self, language: str):
language = language.lower()
@ -15,6 +18,12 @@ class Language:
def __str__(self):
return self.__short
def __hash__(self) -> hash:
return hash(str(self))
def __eq__(self, other: Language):
return str(self) == str(other)
@property
def image_suffix(self):
# supported languages for face URLs
@ -32,4 +41,3 @@ class Language:
return ""
else:
return "_EN"

View file

@ -10,7 +10,7 @@ from .ttsdeck import TTSDeck
class Opus(Cards):
__SQUARE_API_URL = "https://fftcg.square-enix-games.com/de/get-cards"
__SQUARE_API_URL = "https://fftcg.square-enix-games.com/en/get-cards"
def __init__(self, opus_id: str, language: Language):
logger = logging.getLogger(__name__)
@ -64,7 +64,7 @@ class Opus(Cards):
self.sort(key=lambda x: x.code.opus)
for card in self:
logger.info(f"imported card {card}")
logger.debug(f"imported card {card}")
@property
def number(self) -> str:

26
main.py
View file

@ -47,6 +47,12 @@ def main() -> None:
description="Imports FFTCG cards for TT-Sim.",
)
parser.add_argument(
"-v", "--verbose",
help="increase output verbosity",
action="count",
)
parser.add_argument(
"-l", "--language",
type=fftcg.Language,
@ -105,12 +111,25 @@ def main() -> None:
help="the Deck to import",
)
# parse arguments
args = parser.parse_args()
# set up logging
if args.verbose is None:
args.verbose = logging.WARN
elif args.verbose == 1:
args.verbose = logging.INFO
else:
args.verbose = logging.DEBUG
logging.basicConfig(
level=logging.INFO,
level=args.verbose,
format="%(levelname)s: %(processName)s %(message)s",
)
logger = logging.getLogger(__name__)
logger.debug(f"{args = }")
# output directory
if not os.path.exists(OUT_DIR_NAME):
os.mkdir(OUT_DIR_NAME)
@ -118,13 +137,12 @@ def main() -> None:
os.chdir(OUT_DIR_NAME)
# call function based on args
args = parser.parse_args()
for deck in args.func(args):
deck.save()
# bye
logging.info("Done. Put the generated JSON files in your 'Saved Objects' Folder.")
logging.info("Thanks for using fftcgtool!")
print("Done. Put the generated JSON files in your 'Saved Objects' Folder.")
print("Thanks for using fftcgtool!")
if __name__ == "__main__":