From 356a441d8cb12616b9cea0a7a93c576633c4b022 Mon Sep 17 00:00:00 2001 From: Latent Logic Date: Wed, 7 Jun 2017 14:52:11 -0700 Subject: [PATCH 1/9] Use lowercase for matching tags Most of the logic came from @coandco commit 9572b64c6ae50e55ace592217cc879fab8f6a62d Date: Wed Jul 1 10:56:01 2015 -0700 Make card type captialization-agnostic. commit 972f93ddbee1da8071d32f5781927ff49d57bea5 Date: Tue Jun 16 11:27:12 2015 -0700 Fix symbol case sensitivity in a less hackish way. --- TSSSF_CardGen.py | 76 +++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/TSSSF_CardGen.py b/TSSSF_CardGen.py index 4a1e439..7395afa 100644 --- a/TSSSF_CardGen.py +++ b/TSSSF_CardGen.py @@ -93,16 +93,16 @@ ] Frames = { - "START": PIL_Helper.LoadImage(BleedTemplatesPath + "BLEED-Blank-Start-bleed.png"), - "Warning": PIL_Helper.LoadImage(CardPath + "BLEED_Card - Warning.png"), - "Pony": PIL_Helper.LoadImage(BleedTemplatesPath + "BLEED-Blank-Pony-bleed.png"), - "Ship": PIL_Helper.LoadImage(BleedTemplatesPath + "BLEED-Blank-Ship-bleed.png"), - "Rules1": PIL_Helper.LoadImage(CardPath + "BLEED_Rules1.png"), - "Rules3": PIL_Helper.LoadImage(CardPath + "BLEED_Rules3.png"), - "Rules5": PIL_Helper.LoadImage(CardPath + "BLEED_Rules5.png"), - "Goal": PIL_Helper.LoadImage(BleedTemplatesPath + "BLEED-Blank-Goal-bleed.png"), - "Derpy": PIL_Helper.LoadImage(CardPath + "BLEED_Card - Derpy Hooves.png"), - "TestSubject": PIL_Helper.LoadImage(CardPath + "BLEED_Card - OverlayTest Subject Cheerilee.png") + "start": PIL_Helper.LoadImage(BleedTemplatesPath + "BLEED-Blank-Start-bleed.png"), + "warning": PIL_Helper.LoadImage(CardPath + "BLEED_Card - Warning.png"), + "pony": PIL_Helper.LoadImage(BleedTemplatesPath + "BLEED-Blank-Pony-bleed.png"), + "ship": PIL_Helper.LoadImage(BleedTemplatesPath + "BLEED-Blank-Ship-bleed.png"), + "rules1": PIL_Helper.LoadImage(CardPath + "BLEED_Rules1.png"), + "rules3": PIL_Helper.LoadImage(CardPath + "BLEED_Rules3.png"), + "rules5": PIL_Helper.LoadImage(CardPath + "BLEED_Rules5.png"), + "goal": PIL_Helper.LoadImage(BleedTemplatesPath + "BLEED-Blank-Goal-bleed.png"), + "derpy": PIL_Helper.LoadImage(CardPath + "BLEED_Card - Derpy Hooves.png"), + "testsubject": PIL_Helper.LoadImage(CardPath + "BLEED_Card - OverlayTest Subject Cheerilee.png") } Symbols = { @@ -129,7 +129,7 @@ "3-4": PIL_Helper.LoadImage(SymbolsPath + "symbol-34.png"), "2-3": PIL_Helper.LoadImage(SymbolsPath + "symbol-23.png") } -TIMELINE_SYMBOL_LIST = ["Dystopian"] +TIMELINE_SYMBOL_LIST = ["dystopian"] Expansions = { "Everfree14": PIL_Helper.LoadImage(ExpansionIconsPath + "symbol-Everfree14.png"), @@ -196,22 +196,22 @@ } backs = { - "START": PIL_Helper.LoadImage(CardBacksPath + "Back-Start.png"), - "Pony": PIL_Helper.LoadImage(CardBacksPath + "Back-Main.png"), - "Goal": PIL_Helper.LoadImage(CardBacksPath + "Back-Goals.png"), - "Ship": PIL_Helper.LoadImage(CardBacksPath + "Back-Ships.png"), - "Card": PIL_Helper.LoadImage(CardBacksPath + "Back-Main.png"), - "Shipwrecker": PIL_Helper.LoadImage(CardBacksPath + "Back-Main.png"), - "BLANK": PIL_Helper.LoadImage(CardBacksPath + "Blank - Intentionally Left Blank.png"), - "Rules1": PIL_Helper.LoadImage(CardPath + "Rules2.png"), - "Rules3": PIL_Helper.LoadImage(CardPath + "Rules4.png"), - "Rules5": PIL_Helper.LoadImage(CardPath + "Rules6.png"), - "TestSubject": PIL_Helper.LoadImage(CardBacksPath + "Back-Main.png"), - "Warning": PIL_Helper.LoadImage(CardPath + "Card - Contact.png") + "start": PIL_Helper.LoadImage(CardBacksPath + "Back-Start.png"), + "pony": PIL_Helper.LoadImage(CardBacksPath + "Back-Main.png"), + "goal": PIL_Helper.LoadImage(CardBacksPath + "Back-Goals.png"), + "ship": PIL_Helper.LoadImage(CardBacksPath + "Back-Ships.png"), + "card": PIL_Helper.LoadImage(CardBacksPath + "Back-Main.png"), + "shipwrecker": PIL_Helper.LoadImage(CardBacksPath + "Back-Main.png"), + "blank": PIL_Helper.LoadImage(CardBacksPath + "Blank - Intentionally Left Blank.png"), + "rules1": PIL_Helper.LoadImage(CardPath + "Rules2.png"), + "rules3": PIL_Helper.LoadImage(CardPath + "Rules4.png"), + "rules5": PIL_Helper.LoadImage(CardPath + "Rules6.png"), + "testsubject": PIL_Helper.LoadImage(CardBacksPath + "Back-Main.png"), + "warning": PIL_Helper.LoadImage(CardPath + "Card - Contact.png") } -special_card_types = ["Rules1", "Rules3", "Rules5", "Warning", "Derpy", "Card"] -special_cards_with_copyright = ["Derpy"] +special_card_types = ["rules1", "rules3", "rules5", "warning", "derpy", "card"] +special_cards_with_copyright = ["derpy"] def FixFileName(tagin): @@ -304,26 +304,27 @@ def BuildCard(data): def BuildBack(data): if type(data).__name__ == 'dict': - card_type = data['type'] + card_type = data['type'].lower() else: card = data.strip('\n').strip('\r').replace(r'\n', '\n').split('`') - card_type = card[TYPE] + card_type = card[TYPE].lower() return backs[card_type] def PickCardFunc(card_type, data): - if card_type == "START": + card_type = card_type.lower() + if card_type == "start": return MakeStartCard(data) - elif card_type == "Pony": + elif card_type == "pony": return MakePonyCard(data) - elif card_type == "Ship": + elif card_type == "ship": return MakeShipCard(data) - elif card_type == "Goal": + elif card_type == "goal": return MakeGoalCard(data) - elif card_type == "BLANK": + elif card_type == "blank": return MakeBlankCard() - elif card_type == "TestSubject": + elif card_type == "testsubject": return MakePonyCard(data) elif card_type in special_card_types: return MakeSpecialCard(data) @@ -332,7 +333,7 @@ def PickCardFunc(card_type, data): def GetFrame(card_type): - return Frames[card_type].copy() + return Frames[card_type.lower()].copy() def AddCardArt(image, filename, anchor): @@ -351,6 +352,7 @@ def AddCardArt(image, filename, anchor): def AddSymbols(image, symbols, card_type=""): + symbols = [x.lower() for x in symbols] # Remove any timeline symbols from the symbols list pruned_symbols = set(symbols) - set(TIMELINE_SYMBOL_LIST) if card_type == "Goal": @@ -365,7 +367,7 @@ def AddSymbols(image, symbols, card_type=""): positions = [Anchors["Symbol1"], Anchors["Symbol2"]] for index, s in enumerate(symbols): - sym = Symbols.get(s.lower(), None) + sym = Symbols.get(s, None) if sym: if s in TIMELINE_SYMBOL_LIST: image.paste(sym, Anchors["TimelineSymbol"], sym) @@ -673,7 +675,7 @@ def MakeSpecialCard(card): def MakeSpecialCardJSON(data): print repr(data['picture']) image = GetFrame(data['picture']) - if data['picture'] in special_cards_with_copyright: + if data['picture'].lower() in special_cards_with_copyright: CopyrightText(data, image, ColorDict["Copyright"], data.get('artist', ARTIST)) if Expansion_Icon is not None: AddExpansionJSON(image, Expansion_Icon) @@ -683,7 +685,7 @@ def MakeSpecialCardJSON(data): def MakeSpecialCardPON(data): print repr(data[PICTURE]) image = GetFrame(data[PICTURE]) - if data[PICTURE] in special_cards_with_copyright: + if data[PICTURE].lower() in special_cards_with_copyright: CopyrightText(data, image, ColorDict["Copyright"], ARTIST) if len(data) > EXPANSION: AddExpansion(image, data[EXPANSION]) From 35b1b271e65f8d4aae2b6f684c5a2b04e9be8cf9 Mon Sep 17 00:00:00 2001 From: Latent Logic Date: Wed, 7 Jun 2017 14:54:43 -0700 Subject: [PATCH 2/9] Rename CLIENT to COPYRIGHT and allow full line replacement Most of the logic came from @coandco commit 9dc75948814498753d5336717ba3fe5860923e48 Date: Sat Jun 20 13:22:44 2015 -0700 Add support for arbitrary copyright lines to the backend. --- TSSSF_CardGen.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/TSSSF_CardGen.py b/TSSSF_CardGen.py index 7395afa..96e16be 100644 --- a/TSSSF_CardGen.py +++ b/TSSSF_CardGen.py @@ -1,7 +1,7 @@ import os, glob, shutil, traceback, random import PIL_Helper -TYPE, PICTURE, SYMBOLS, TITLE, KEYWORDS, BODY, FLAVOR, EXPANSION, CLIENT = range(9) +TYPE, PICTURE, SYMBOLS, TITLE, KEYWORDS, BODY, FLAVOR, EXPANSION, COPYRIGHT = range(9) DIRECTORY = "TSSSF" ARTIST = "Pixel Prism" @@ -493,15 +493,18 @@ def CopyrightText(card, image, color, artist): if type(card).__name__ == 'dict': client = card.get('client') else: - if len(card) - 1 >= CLIENT: - client = str(card[CLIENT]) + if len(card) - 1 >= COPYRIGHT: + client = str(card[COPYRIGHT]) if client is not None: card_set += " " + client - text = "{}; TSSSF by Horrible People Games. Art by {}.".format( - card_set, - artist - ) + if "TSSSF by Horrible People Games" in client: + text = client + else: + text = "{}; TSSSF by Horrible People Games. Art by {}.".format( + card_set, + artist + ) PIL_Helper.AddText( image=image, text=text, From 39540b7cadafee71cece9e496d3938f6a8a8411d Mon Sep 17 00:00:00 2001 From: Latent Logic Date: Wed, 7 Jun 2017 14:56:49 -0700 Subject: [PATCH 3/9] Add the web icons to the Expansions dictionary Most of the logic came from @coandco commit f0ea4f85f2485a24e7cdf125f9ffad7d9cda13cf Date: Thu Jun 25 18:48:07 2015 -0700 Add support for multiple web expansion symbol types. --- TSSSF_CardGen.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/TSSSF_CardGen.py b/TSSSF_CardGen.py index 96e16be..1e9b951 100644 --- a/TSSSF_CardGen.py +++ b/TSSSF_CardGen.py @@ -155,7 +155,10 @@ "Ponycon 2015": PIL_Helper.LoadImage(ExpansionIconsPath + "symbol-ponynyc.png"), "Patreon": PIL_Helper.LoadImage(ExpansionIconsPath + "symbol-Patreon.png"), "Gameshow": PIL_Helper.LoadImage(ExpansionIconsPath + "symbol-gameshow.png"), - "BABScon": PIL_Helper.LoadImage(ExpansionIconsPath + "symbol-BABScon.png") + "BABScon": PIL_Helper.LoadImage(ExpansionIconsPath + "symbol-BABScon.png"), + "web-outline": PIL_Helper.LoadImage(ExpansionIconsPath + "symbol-web-circledark.png"), + "web-white": PIL_Helper.LoadImage(ExpansionIconsPath + "symbol-www.png"), + "web-grey": PIL_Helper.LoadImage(ExpansionIconsPath + "symbol-web-circlegrey.png") } ColorDict = { From cc2f40c01992fe4e8d8beab84c9e77a799fd0f46 Mon Sep 17 00:00:00 2001 From: Latent Logic Date: Thu, 8 Jun 2017 10:53:19 -0700 Subject: [PATCH 4/9] Allow images with wrong aspect-ratio to fit Most of the logic came from @coandco commit 7020eacd1bd9ceec1252ed51a42fa0faa154bf6a Date: Thu Jun 11 00:18:05 2015 -0700 Improve art-resizing code to work with any aspect ratio. --- TSSSF_CardGen.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/TSSSF_CardGen.py b/TSSSF_CardGen.py index 1e9b951..2452ba3 100644 --- a/TSSSF_CardGen.py +++ b/TSSSF_CardGen.py @@ -34,6 +34,7 @@ VassalCard = [0] ART_WIDTH = 600 +ART_HEIGHT = 443 base_w = 889 base_h = 1215 base_w_center = base_w / 2 @@ -44,6 +45,7 @@ textmaxwidth = 689 croprect = (50, 63, 788 + 50, 1088 + 63) +ART_CROPRECT=(0,0,ART_WIDTH, ART_HEIGHT) TextHeightThresholds = [363, 378, 600] TitleWidthThresholds = [50] # This is in #characters, fix later plox @@ -348,9 +350,16 @@ def AddCardArt(image, filename, anchor): art = random.choice(ArtMissing) # Find desired height of image based on width of 600 px w, h = art.size - h = int((float(ART_WIDTH) / w) * h) - # Resize image to fit in frame - art = PIL_Helper.ResizeImage(art, (ART_WIDTH, h)) + if float(w) / float(h) < float(ART_WIDTH) / float(ART_HEIGHT): + h = int((float(ART_WIDTH) / w) * h) + # Resize image to fit in frame + art = PIL_Helper.ResizeImage(art, (ART_WIDTH, h)) + else: + w = int((float(ART_HEIGHT) / h) * w) + # Resize image to fit in frame + art = PIL_Helper.ResizeImage(art, (w, ART_HEIGHT)) + + art = art.crop(ART_CROPRECT) image.paste(art, anchor) From 53b9a29e2f44668dfc3f6b2f49b4384c81e98f57 Mon Sep 17 00:00:00 2001 From: Latent Logic Date: Thu, 8 Jun 2017 10:55:40 -0700 Subject: [PATCH 5/9] Add placeholder art to match TSSSFTemplates:web_generator --- TSSSF_CardGen.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/TSSSF_CardGen.py b/TSSSF_CardGen.py index 2452ba3..e6b5d53 100644 --- a/TSSSF_CardGen.py +++ b/TSSSF_CardGen.py @@ -26,6 +26,7 @@ ExpansionIconsPath = ResourcePath + "/expansion icons/" CardBacksPath = ResourcePath + "/card backs/" FontsPath = ResourcePath + "/fonts/" +PlaceholderPath = ResourcePath + "/placeholder art/" VassalTemplatesPath = DIRECTORY + "/vassal templates/" VassalWorkspacePath = DIRECTORY + "/vassal workspace/" @@ -85,13 +86,13 @@ } ArtMissing = [ - PIL_Helper.LoadImage(CardPath + "artmissing01.png"), - PIL_Helper.LoadImage(CardPath + "artmissing02.png"), - PIL_Helper.LoadImage(CardPath + "artmissing03.png"), - PIL_Helper.LoadImage(CardPath + "artmissing04.png"), - PIL_Helper.LoadImage(CardPath + "artmissing05.png"), - PIL_Helper.LoadImage(CardPath + "artmissing06.png"), - PIL_Helper.LoadImage(CardPath + "artmissing07.png"), + PIL_Helper.LoadImage(PlaceholderPath + "artmissing01.png"), + PIL_Helper.LoadImage(PlaceholderPath + "artmissing02.png"), + PIL_Helper.LoadImage(PlaceholderPath + "artmissing03.png"), + PIL_Helper.LoadImage(PlaceholderPath + "artmissing04.png"), + PIL_Helper.LoadImage(PlaceholderPath + "artmissing05.png"), + PIL_Helper.LoadImage(PlaceholderPath + "artmissing06.png"), + PIL_Helper.LoadImage(PlaceholderPath + "artmissing07.png"), ] Frames = { From 2b29c8e2ec700f89e137b0b47fe6705592d1b7c0 Mon Sep 17 00:00:00 2001 From: Latent Logic Date: Thu, 8 Jun 2017 10:56:50 -0700 Subject: [PATCH 6/9] Allow earth pony with or without a space. The "earth pony" string is the only one that used a space. Add a second entry in the dictionary to allow "earthpony" to be used as well for consistency --- TSSSF_CardGen.py | 1 + 1 file changed, 1 insertion(+) diff --git a/TSSSF_CardGen.py b/TSSSF_CardGen.py index e6b5d53..805ba3e 100644 --- a/TSSSF_CardGen.py +++ b/TSSSF_CardGen.py @@ -113,6 +113,7 @@ "female": PIL_Helper.LoadImage(SymbolsPath + "Symbol-Female.png"), "malefemale": PIL_Helper.LoadImage(SymbolsPath + "Symbol-MaleFemale.png"), "earth pony": PIL_Helper.LoadImage(SymbolsPath + "Symbol-Earth-Pony.png"), + "earthpony": PIL_Helper.LoadImage(SymbolsPath + "Symbol-Earth-Pony.png"), "unicorn": PIL_Helper.LoadImage(SymbolsPath + "Symbol-Unicorn.png"), "uniearth": PIL_Helper.LoadImage(SymbolsPath + "symbol-uniearth.png"), "pegasus": PIL_Helper.LoadImage(SymbolsPath + "Symbol-Pegasus.png"), From c6a53ea110f84d0945bf9ff6cb6fe7105635f01b Mon Sep 17 00:00:00 2001 From: Latent Logic Date: Thu, 8 Jun 2017 10:58:56 -0700 Subject: [PATCH 7/9] Allow web links as image filenames for card art. Most of the logic came from @coandco commit 04d4665a7fbd0ded0c424cefe1bf46c9a1354336 Date: Sun Jun 7 23:41:47 2015 -0700 First pass at allowing URLs as card-art. commit a7aac4f075da53ddafa024ffa89dd3c5233b78e0 Date: Mon Jun 22 00:13:07 2015 -0700 Insert placeholder art if art string is blank. --- PIL_Helper.py | 15 ++++++++++++++- TSSSF_CardGen.py | 7 ++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/PIL_Helper.py b/PIL_Helper.py index f9c22e0..ec29b64 100644 --- a/PIL_Helper.py +++ b/PIL_Helper.py @@ -1,7 +1,14 @@ from PIL import Image, ImageFont, ImageDraw, ImageOps -import os, glob +from StringIO import StringIO +import os, glob, requests from math import ceil +class BadNetStatusException(Exception): + ''' + An exception for LoadImageFromURL to throw if it has + problems fetching the remote URL. + ''' + def BuildFont(fontname, fontsize): return ImageFont.truetype(fontname, fontsize) @@ -201,6 +208,12 @@ def BuildPage(card_list, grid_width, grid_height, filename, def BlankImage(w, h, color=(255,255,255), image_type="RGBA"): return Image.new(image_type, (w, h), color=color) +def LoadImageFromURL(url): + r = requests.get(url) + if r.status_code is not 200: + raise BadNetStatusException(r.status_code) + return Image.open(StringIO(r.content)) + def LoadImage(filepath, fallback="blank.png"): try: return Image.open(filepath) diff --git a/TSSSF_CardGen.py b/TSSSF_CardGen.py index 805ba3e..5ce18bd 100644 --- a/TSSSF_CardGen.py +++ b/TSSSF_CardGen.py @@ -346,7 +346,12 @@ def GetFrame(card_type): def AddCardArt(image, filename, anchor): if filename == "NOART": return - if os.path.exists(os.path.join(CardPath, filename)): + if filename.startswith("http"): + try: + art = PIL_Helper.LoadImageFromURL(filename) + except PIL_Helper.BadNetStatusException as e: + art = random.choice(ArtMissing) + elif os.path.exists(os.path.join(CardPath, filename)) and filename != "": art = PIL_Helper.LoadImage(os.path.join(CardPath, filename)) else: art = random.choice(ArtMissing) From a158f0a23090dfa6c0f8081676f2a65321985046 Mon Sep 17 00:00:00 2001 From: Latent Logic Date: Thu, 8 Jun 2017 23:46:52 -0700 Subject: [PATCH 8/9] Allow building of a single card at a time Most of the logic came from @coandco https://github.com/coandco/CardMachine/tree/web_generator --- .gitignore | 4 ++ TSSSF_CardGen.py | 7 +++ imgur_auth.py | 4 ++ single_card.py | 139 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 imgur_auth.py create mode 100755 single_card.py diff --git a/.gitignore b/.gitignore index f48aa5b..49dc3ce 100644 --- a/.gitignore +++ b/.gitignore @@ -106,3 +106,7 @@ $RECYCLE.BIN/ BaBOC/ TSSSF/ WSotT/ + +# Key-containing config +# ========================= +imgur_auth.py diff --git a/TSSSF_CardGen.py b/TSSSF_CardGen.py index 5ce18bd..cb0fbff 100644 --- a/TSSSF_CardGen.py +++ b/TSSSF_CardGen.py @@ -269,6 +269,13 @@ def SaveCard(filepath, image_to_save): filepath = "{}_{:>03}{}".format(basepath, i, extension) image_to_save.save(filepath, dpi=(300, 300)) +def BuildSingleCard(linein): + tags = linein.strip('\n').strip('\r').replace(r'\n', '\n').split('`') + im_bleed = PickCardFunc(tags[TYPE], tags) + im_crop = im_bleed.crop(croprect) + im_vassal = PIL_Helper.ResizeImage(im_crop, VASSAL_SCALE) + + return (im_bleed, im_crop, im_vassal) def BuildCard(data): picture = None diff --git a/imgur_auth.py b/imgur_auth.py new file mode 100644 index 0000000..14c7462 --- /dev/null +++ b/imgur_auth.py @@ -0,0 +1,4 @@ +#If you wish to use imgur-save functionality, put your API key here +CLIENT_ID = '' +CLIENT_SECRET = '' + diff --git a/single_card.py b/single_card.py new file mode 100755 index 0000000..fafbe7e --- /dev/null +++ b/single_card.py @@ -0,0 +1,139 @@ +#!/usr/bin/python +''' +Generate a single card +''' +import argparse +import base64 +import traceback +import sys +import urllib +import requests +import TSSSF_CardGen +import json +import imgur_auth +import re +from StringIO import StringIO + + +def SaveCardToFile(image_object, location): + image_object.save(location, format="PNG", dpi=(300, 300)) + return location + + +def SaveCardToURL(image_object): + fileobj = StringIO() + image_object.save(fileobj, format="PNG", dpi=(300, 300)) + encoded_image = fileobj.getvalue().encode("base64") + return("data:image/png;base64," + urllib.quote(encoded_image)) + + +def GetImgurCredits(): + credits = requests.get( + 'https://api.imgur.com/3/credits.json', + headers={'Authorization': 'Client-ID %s' % imgur_auth.CLIENT_ID}, + data={'key': imgur_auth.CLIENT_SECRET} + ) + print "Full GetCredits retval: %r" % credits.text + return json.loads(credits.text)["data"]["ClientRemaining"] + + +def SaveCardToImgur(image_object, title=None, desc=None): + #Make sure we have the budget to do this + if GetImgurCredits() < 10: + raise ValueError("Insufficient imgur credits remaining") + fileobj = StringIO() + image_object.save(fileobj, format="PNG", dpi=(300, 300)) + + img_json = requests.post( + 'https://api.imgur.com/3/upload.json', + headers={'Authorization': 'Client-ID %s' % imgur_auth.CLIENT_ID}, + data={ + 'key': imgur_auth.CLIENT_SECRET, + 'title': title or 'Card generated with TSSSF Card Generator', + 'description': desc or '', + 'type': 'base64', + 'image': fileobj.getvalue().encode("base64") + } + ) + #return img_json.text + return json.loads(img_json.text)["data"]["id"] + + +def SaveCard(image, save_type, location=None, imgurtitle=None, imgurdesc=None): + if save_type == "file": + retval = SaveCardToFile(image, location) + elif save_type == "encoded_url": + retval = SaveCardToURL(image) + elif save_type == "imgur": + retval = SaveCardToImgur(image, imgurtitle, imgurdesc) + else: + raise ValueError("save type not recognized") + return retval + + +def make_single_card(card_line, output_file, image_type, save_type, + imgurtitle, imgurdesc): + im = {} + + print("Attempting to build card %r" % card_line) + (im["bleed"], + im["cropped"], + im["vassal"]) = TSSSF_CardGen.BuildSingleCard(card_line) + + return SaveCard(im[image_type], save_type, output_file, imgurtitle, + imgurdesc) + +if __name__ == '__main__': + ACTUAL_STDOUT = sys.stdout + sys.stdout = sys.stderr + parser = argparse.ArgumentParser(prog="single_card.py") + + parser.add_argument('-c', '--card_line', + help="Base64-encoded single-line PON card definition", + required=True) + parser.add_argument('-o', '--output', + help="File to write card to", + default=None) + parser.add_argument('-i', '--imagetype', + help="Set image type to output", + choices=("bleed", "cropped", "vassal"), + default="cropped") + parser.add_argument('-r', '--returntype', + help="Output format", + choices=("file", "encoded_url", "imgur"), + default="cropped") + parser.add_argument('-t', '--imgurtitle', + help="Base64-encoded alternate imgur title", + default=None) + parser.add_argument('-d', '--imgurdesc', + help="Base64-encoded alternate imgur description", + default=None) + + args = parser.parse_args() + + if args.returntype == "file" and args.output is None: + parser.error("--output must be defined if --returntype is set to file") + + try: + CARD_LINE = base64.b64decode(args.card_line).decode('utf-8') + IMGURTITLE = args.imgurtitle + if IMGURTITLE is not None: + IMGURTITLE = base64.b64decode(IMGURTITLE) + IMGURDESC = args.imgurdesc + if IMGURDESC is not None: + IMGURDESC = base64.b64decode(IMGURDESC) + except Exception: + print(traceback.format_exc()) + print("Failed to base64 decode a string") + sys.exit(1) + OUTPUT = "" + try: + OUTPUT = make_single_card(CARD_LINE, args.output, args.imagetype, + args.returntype, IMGURTITLE, IMGURDESC) + except Exception: + print(traceback.format_exc()) + print("Failed to build single card %r" % CARD_LINE) + sys.exit(1) + print >> ACTUAL_STDOUT, OUTPUT + print("Success!") + sys.exit(0) From 5d002e682b1524232feb27b4d56541c71eaa6511 Mon Sep 17 00:00:00 2001 From: Latent Logic Date: Mon, 12 Jun 2017 20:30:21 -0700 Subject: [PATCH 9/9] Update ascii text parsing to be unicode safe. Fixes coandco/TSSSF-Frontend#20 --- PIL_Helper.py | 2 +- TSSSF_CardGen.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PIL_Helper.py b/PIL_Helper.py index ec29b64..7cf66ea 100644 --- a/PIL_Helper.py +++ b/PIL_Helper.py @@ -108,7 +108,7 @@ def AddText(image, text, font, fill=(0,0,0), anchor=(0,0), # If current line is blank, just change y and skip to next if not line == "": if padline == True: - line = " {0} ".format(line) + line = u" {0} ".format(line) line_width, line_height = font.getsize(line) if halign == "left": x_pos = start_x diff --git a/TSSSF_CardGen.py b/TSSSF_CardGen.py index cb0fbff..cbfce12 100644 --- a/TSSSF_CardGen.py +++ b/TSSSF_CardGen.py @@ -520,7 +520,7 @@ def CopyrightText(card, image, color, artist): client = card.get('client') else: if len(card) - 1 >= COPYRIGHT: - client = str(card[COPYRIGHT]) + client = unicode(card[COPYRIGHT]) if client is not None: card_set += " " + client