2021-08-04 16:36:23 +00:00
|
|
|
import logging
|
|
|
|
|
|
|
|
from PIL import Image
|
|
|
|
|
2021-08-04 22:40:32 +00:00
|
|
|
from .cards import Cards
|
2021-08-04 16:36:23 +00:00
|
|
|
from .imageloader import ImageLoader
|
|
|
|
|
|
|
|
|
2021-08-09 03:32:05 +00:00
|
|
|
def chunks(whole: list[any], chunk_size) -> list:
|
2021-08-04 16:36:23 +00:00
|
|
|
# while there are elements
|
|
|
|
while whole:
|
|
|
|
# get a chunk
|
|
|
|
yield whole[:chunk_size]
|
|
|
|
# remove that chunk
|
|
|
|
whole = whole[chunk_size:]
|
2021-08-04 01:39:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
class Book:
|
2021-08-04 22:17:47 +00:00
|
|
|
# Card faces by Square API
|
|
|
|
__FACE_URL = "https://fftcg.cdn.sewest.net/images/cards/full/{}_{}.jpg"
|
|
|
|
|
|
|
|
# Card back image by Aurik
|
|
|
|
__BACK_URL = "http://cloud-3.steamusercontent.com/ugc/948455238665576576/85063172B8C340602E8D6C783A457122F53F7843/"
|
|
|
|
|
2021-08-09 03:32:05 +00:00
|
|
|
def __init__(self, cards: Cards, grid: tuple[int, int], resolution: tuple[int, int], language: str,
|
2021-08-09 02:03:24 +00:00
|
|
|
num_threads: int):
|
2021-08-04 16:36:23 +00:00
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
2021-08-04 22:33:18 +00:00
|
|
|
# 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])
|
|
|
|
|
2021-08-04 22:17:47 +00:00
|
|
|
# all card face URLs
|
|
|
|
urls = [Book.__FACE_URL.format(card.code, language) for card in cards]
|
|
|
|
# card back URL
|
|
|
|
urls.append(Book.__BACK_URL)
|
|
|
|
|
|
|
|
# multithreaded download
|
|
|
|
images = ImageLoader.load(urls, resolution, language, num_threads)
|
|
|
|
# card back Image
|
|
|
|
back_image = images.pop(-1)
|
2021-08-04 01:39:19 +00:00
|
|
|
|
2021-08-04 16:36:23 +00:00
|
|
|
# shorthands
|
|
|
|
# rows and columns per sheet
|
2021-08-04 01:39:19 +00:00
|
|
|
r, c = grid
|
2021-08-04 22:17:47 +00:00
|
|
|
# capacity of grid (reserve last space for card back)
|
|
|
|
grid_capacity = r * c - 1
|
2021-08-04 16:36:23 +00:00
|
|
|
# width, height per card
|
|
|
|
w, h = resolution
|
|
|
|
|
2021-08-09 03:44:12 +00:00
|
|
|
def paste_card(index: int, card: Image) -> None:
|
2021-08-04 22:17:47 +00:00
|
|
|
x, y = (index % c) * w, (index // c) * h
|
2021-08-09 03:44:12 +00:00
|
|
|
page.paste(card, (x, y))
|
2021-08-04 22:17:47 +00:00
|
|
|
|
2021-08-04 16:36:23 +00:00
|
|
|
self.__pages = []
|
2021-08-04 22:17:47 +00:00
|
|
|
for images in chunks(images, grid_capacity):
|
|
|
|
# create book page Image
|
2021-08-04 16:36:23 +00:00
|
|
|
page = Image.new("RGB", (c * w, r * h))
|
|
|
|
logger.info(f"New image: {page.size[0]}x{page.size[1]}")
|
|
|
|
|
2021-08-04 22:17:47 +00:00
|
|
|
# paste card faces onto page
|
2021-08-04 16:36:23 +00:00
|
|
|
for i, image in enumerate(images):
|
2021-08-09 03:44:12 +00:00
|
|
|
paste_card(i, image)
|
2021-08-04 22:17:47 +00:00
|
|
|
|
|
|
|
# paste card back in last position
|
2021-08-09 03:44:12 +00:00
|
|
|
paste_card(c * r - 1, back_image)
|
2021-08-04 16:36:23 +00:00
|
|
|
|
|
|
|
self.__pages.append(page)
|
|
|
|
|
2021-08-09 02:03:24 +00:00
|
|
|
def save(self, filename: str) -> None:
|
2021-08-04 16:36:23 +00:00
|
|
|
for i, page in enumerate(self.__pages):
|
|
|
|
page.save(filename.format(i))
|