#!/usr/bin/env python3 import json import math import os import subprocess import sys from lxml import etree from PIL import Image if getattr(sys, 'frozen', False): # we are running in a bundle bundle_dir = sys._MEIPASS else: # we are running in a normal Python environment bundle_dir = os.path.dirname(os.path.abspath(__file__)) CARD_WIDTH = 181 * 4 CARD_HEIGHT = 253 * 4 def setText(tree, id, text): element = tree.find('.//*[@id="' + id + '"]') if element is None: print("id", id, "not found") return elif element.tag == "{http://www.w3.org/2000/svg}flowRoot": element.find("{http://www.w3.org/2000/svg}flowPara").text = text else: element[0].text = str(text) def removeElement(tree, id): mark = tree.find('.//*[@id="' + id + '"]') if mark is not None: mark.getparent().remove(mark) def makeSVG(base, properties): tree = etree.parse(base) for id, text in properties.items(): if id not in ["count", "art"]: setText(tree, id, text) # remove HP mark if there is no hp if "hp" not in properties: removeElement(tree, "hpMark") if "art" in properties: art = tree.find('.//*[@id="art"]') if art is not None: art.set("{http://www.w3.org/1999/xlink}href", "file://" + bundle_dir + "/" + properties["art"]) return tree def addCardToBase(svg, baseImg, baseX, cardNum): # TODO: possible to remove all this writing to temp files? dest = "out/fig" + str(cardNum) svg.write(dest + ".svg") subprocess.call(["inkscape", "-z", "-f", dest + ".svg", "-w", str(CARD_WIDTH), "-e", dest + ".png"]) cardImg = Image.open(dest + ".png") baseImg.paste(cardImg, ((cardNum % baseX) * cardImg.width, int(cardNum / baseX) * cardImg.height)) def makeFace(baseImage, baseX, cardNum, base, card): fig = makeSVG(base, card) addCardToBase(fig, baseImage, baseX, cardNum) def makeFaces(deckJson, outfile): baseX = math.ceil(math.sqrt(len(deckJson['deck']) + len(deckJson['character']) * 2)) baseImage = Image.new('RGB', (CARD_WIDTH * baseX, CARD_HEIGHT * baseX)) cardType = deckJson["type"] cardNum = 0 # Make a card for each character card if cardType == "hero": for card in deckJson['character']: makeFace(baseImage, baseX, cardNum, os.path.join("images", cardType, "charFront.svg"), card) cardNum += 1 makeFace(baseImage, baseX, cardNum, os.path.join("images", cardType, "charBack.svg"), card) cardNum += 1 if cardType == "villain": pass # Make a card for each card for card in deckJson['deck']: makeFace(baseImage, baseX, cardNum, os.path.join("images", cardType, "card.svg"), card) cardNum += 1 baseImage.save(outfile + ".png", "PNG") return baseX def makeJson(deckJson, imgWidth, outfile): with open(bundle_dir + "/templates/deck.json") as f: outJson = json.load(f) with open(bundle_dir + "/templates/card.json") as f: cardTemplate = json.load(f) # number of cards in x and y direction outJson['ObjectStates'][0]['CustomDeck']['1'].update( {"NumWidth": imgWidth, "NumHeight": imgWidth, #"FaceURL": "http://adam-desktop.dyn.wpi.edu:8000/" + outfile + ".png", "FaceURL": "file://" + os.getcwd() + "/" + outfile + ".png", "BackURL": "http://cloud-3.steamusercontent.com/ugc/156906385556221451/CE2C3AFE1759790CB0B532FFD636D05A99EC91F4/"}) # decks start at (10 * deck id) cardNum = 100 for card in deckJson['character']: outJson['ObjectStates'][0]['DeckIDs'].append(cardNum) # add front card with back as second state cardOutBack = cardTemplate.copy() cardOutBack.update({"Nickname": card['name'], "Description": "Incapacitated", "CardID": cardNum + 1}) cardOut = cardTemplate.copy() cardOut.update({"Nickname": card['name'], "Description": "Active", "CardID": cardNum, "States": {"2": cardOutBack}}) outJson['ObjectStates'][0]['ContainedObjects'].append(cardOut) cardNum += 2 for card in deckJson['deck']: for i in range(0, card['count']): outJson['ObjectStates'][0]['DeckIDs'].append(cardNum) # add a card object thing for each card, and give it a name cardOut = cardTemplate.copy() cardOut.update({"Nickname": card['name'], "Description": card.get('type', ""), "CardID": cardNum}) outJson['ObjectStates'][0]['ContainedObjects'].append(cardOut) cardNum += 1 with open(outfile + ".json", "w") as f: json.dump(outJson, f) if __name__ == '__main__': if len(sys.argv) < 3: print("not enough arguments!") inputJson = input("Input file: ") outfile = input("Output file (no suffix): ") else: inputJson = sys.argv[1] outfile = sys.argv[2] with open(inputJson) as f: deckJson = json.load(f) imgWidth = makeFaces(deckJson, outfile) makeJson(deckJson, imgWidth, outfile)