From 1bc3c724a1fe7d389089bfe9369a655938a558f5 Mon Sep 17 00:00:00 2001 From: PAK90 Date: Sat, 8 Aug 2015 15:03:37 -0600 Subject: [PATCH] Added MSE2 export feature. --- decode.py | 30 +++++++++++++++--- lib/cardlib.py | 86 +++++++++++++++++++++++++++++++++++++++++++++++--- lib/utils.py | 3 ++ 3 files changed, 111 insertions(+), 8 deletions(-) diff --git a/decode.py b/decode.py index e6a1516..b3292f5 100755 --- a/decode.py +++ b/decode.py @@ -1,6 +1,11 @@ +#!c:/Python27/python.exe -u #!/usr/bin/env python import sys import os +import zipfile +import shutil + +#to use: py decode.py homebrew.txt homepretty.txt --norarity -v -mse in mtgencode folder. libdir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'lib') sys.path.append(libdir) @@ -14,7 +19,7 @@ def exclude_sets(cardset): return cardset == 'Unglued' or cardset == 'Unhinged' or cardset == 'Celebration' def main(fname, oname = None, verbose = True, - gatherer = False, for_forum = False, creativity = False, norarity = False): + gatherer = False, for_forum = False, creativity = False, norarity = False, for_mse = False): cards = [] valid = 0 invalid = 0 @@ -107,9 +112,12 @@ def main(fname, oname = None, verbose = True, namediff = Namediff() def writecards(writer): + if for_mse: + # have to prepend a massive chunk. + writer.write(utils.mse_prepend) for card in cards: - writer.write((card.format(gatherer = gatherer, for_forum = for_forum)).encode('utf-8')) - if creativity: + writer.write((card.format(gatherer = gatherer, for_forum = for_forum, for_mse = for_mse)).encode('utf-8')) + if creativity and not for_mse: # this won't end well if mse mode is enabled. writer.write('~~ closest cards ~~\n'.encode('utf-8')) nearest = cbow.nearest(card) for dist, cardname in nearest: @@ -125,12 +133,25 @@ def main(fname, oname = None, verbose = True, cardname = '[card]' + cardname + '[/card]' writer.write((cardname + ': ' + str(dist) + '\n').encode('utf-8')) writer.write('\n'.encode('utf-8')) + if for_mse: + writer.write('version control:\n\ttype: none\napprentice code: ') # have to append some junk at the end of file. if oname: if verbose: print 'Writing output to: ' + oname with open(oname, 'w') as ofile: writecards(ofile) + if for_mse: + shutil.copyfile(oname, 'set') # copy whatever output file is produced, name the copy 'set' (yes, no extension). + zf = zipfile.ZipFile(oname+'.mse-set', mode='w') # use the freaky mse extension instead of zip. + try: + zf.write('set') # zip up the set file into oname.mse-set. + finally: + print 'Made an MSE set file called ' + oname + '.mse-set.' + zf.close() + os.remove('set') # the set file is useless outside the .mse-set, delete it. + + else: writecards(sys.stdout) sys.stdout.flush() @@ -154,9 +175,10 @@ if __name__ == '__main__': help='the card format has no rarity field; use for legacy input') parser.add_argument('-v', '--verbose', action='store_true', help='verbose output') + parser.add_argument('-mse', '--mse', action='store_true', help='use Magic Set Editor 2 encoding; will output as .mse-set file') args = parser.parse_args() main(args.infile, args.outfile, verbose = args.verbose, gatherer = args.gatherer, for_forum = args.forum, creativity = args.creativity, - norarity = args.norarity) + norarity = args.norarity, for_mse = args.mse) exit(0) diff --git a/lib/cardlib.py b/lib/cardlib.py index 718155a..3d69128 100644 --- a/lib/cardlib.py +++ b/lib/cardlib.py @@ -141,7 +141,7 @@ def fields_check_valid(fields): # layout - string # rarity - string # flavor - string -# artis - string +# artist - string # number - string # multiverseid - number # variations - list @@ -530,7 +530,7 @@ class Card: return outstr - def format(self, gatherer = False, for_forum = False): + def format(self, gatherer = False, for_forum = False, for_mse = False): outstr = '' if gatherer: cardname = titlecase(self.__dict__[field_name]) @@ -606,7 +606,7 @@ class Card: outstr += '[/i]' outstr += '\n' - else: + elif for_forum: cardname = self.__dict__[field_name] outstr += cardname if self.__dict__[field_rarity]: @@ -657,7 +657,85 @@ class Card: outstr += '<' + str(idx) + '> ' + str(value) outstr += '\n' - if self.bside: + + elif for_mse: + # need a 'card' string first + outstr += 'card:\n' + cardname = titlecase(self.__dict__[field_name]) + outstr += '\tname: ' + cardname + '\n' + if self.__dict__[field_rarity]: + if self.__dict__[field_rarity] in utils.json_rarity_unmap: + rarity = utils.json_rarity_unmap[self.__dict__[field_rarity]] + else: + rarity = self.__dict__[field_rarity] + outstr += '\trarity: ' + rarity.lower() + '\n' + #if not self.parsed: + # outstr += ' _UNPARSED_' + #if not self.valid: + # outstr += ' _INVALID_' + + outstr += '\tcasting cost: ' + self.__dict__[field_cost].format(for_forum = for_forum).replace('{','').replace('}','') + outstr += '\n' + + if "planeswalker" in str(self.__dict__[field_types]): + #print 'Walker detected! ' + cardname + outstr += '\tstylesheet: m15-planeswalker\n' + if self.__dict__[field_loyalty]: + outstr += '\tloyalty: ' + utils.from_unary(self.__dict__[field_loyalty]) + '\n' + + outstr += '\tsuper type: ' + ' '.join(self.__dict__[field_supertypes] + self.__dict__[field_types]).title() + '\n' + #outstr += 'sub type: ' + ' '.join(self.__dict__[field_types]) + if self.__dict__[field_subtypes]: + outstr += '\tsub type: ' + ' '.join(self.__dict__[field_subtypes]).title() + outstr += '\n' + + if self.__dict__[field_text].text: + mtext = self.__dict__[field_text].text + mtext = transforms.text_unpass_1_choice(mtext, delimit = True) + mtext = transforms.text_unpass_2_counters(mtext) + mtext = transforms.text_unpass_3_unary(mtext) + mtext = transforms.text_unpass_4_symbols(mtext, for_forum) + mtext = transforms.text_unpass_5_cardname(mtext, cardname) + mtext = transforms.text_unpass_6_newlines(mtext) + newtext = Manatext('') + newtext.text = mtext + newtext.costs = self.__dict__[field_text].costs + newtext = newtext.format(for_forum = for_forum) + newtext = newtext.replace('@',cardname) # first let's put the cardname where all the @s are. + newtext = newtext.replace("uncast","counter") # now replace 'uncast' with 'counter'. + newtext = newtext.replace('{','').replace('}','') # now we encase mana/tap symbols with the correct tags for mse. + linecount = newtext.count('\n') + 1 # adding 1 because no newlines means 1 line, 1 newline means 2 lines etc. + # ok, let's capitalize every letter after a \n... + # first let's find all indices of \n. + indices = [0] # initialise with 0, since we always want to capitalise the first letter. + for i in range (len(newtext)): + if newtext[i] == '\n': + indices.append(i + 1) # we want the index of the letter after the \n, so add one. + indexSet = set(indices) # convert it to a set for the next part; the capitalisation. + newtext = "".join(c.upper() if i in indexSet else c for i, c in enumerate(newtext)) + + # have to do special snowflake stuff for rule text with more than 1 line. 2 or more lines need to be double-indented... + if linecount == 1: + outstr += '\trule text: ' + newtext + '\n' + elif linecount > 1: + newtext = newtext.replace('\n','\n\t\t') + outstr += '\trule text:\n\t\t' + newtext + '\n' + + # also uncast still exists at this point? weird. should be 'unpassed' apparently. until then, did a manual replace. + + if self.__dict__[field_pt]: + ptstring = utils.from_unary(self.__dict__[field_pt]).split('/') + if (len(ptstring) > 1): #really don't want to be accessing anything nonexistent. + outstr += '\tpower: ' + ptstring[0] + '\n' + outstr += '\ttoughness: ' + ptstring[1] + '\n' + #outstr += '\n' + + # now append all the other useless fields that the setfile expects. + outstr += '\thas styling: false\n\tnotes:\n\ttime created:2015-07-20 22:53:07\n\ttime modified:2015-07-20 22:53:08\n\textra data:\n\timage:\n\tcard code text:\n\tcopyright:\n\timage 2:\n\tcopyright 2: ' + + #print outstr + + if self.bside and not for_mse: outstr += utils.dash_marker * 8 + '\n' outstr += self.bside.format(gatherer = gatherer, for_forum = for_forum) diff --git a/lib/utils.py b/lib/utils.py index bf51e6a..a2fc877 100644 --- a/lib/utils.py +++ b/lib/utils.py @@ -6,6 +6,9 @@ import re import config +# special chunk of text that Magic Set Editor 2 requires at the start of all set files. +mse_prepend = 'mse version: 0.3.8\ngame: magic\nstylesheet: m15\nset info:\n\tsymbol:\nstyling:\n\tmagic-m15:\n\t\ttext box mana symbols: magic-mana-small.mse-symbol-font\n\t\toverlay:\n\tmagic-m15-clear:\n\t\ttext box mana symbols: magic-mana-small.mse-symbol-font\n\t\toverlay: \n\tmagic-m15-extra-improved:\n\t\ttext box mana symbols: magic-mana-small.mse-symbol-font\n\t\tpt box symbols: magic-pt-symbols-extra.mse-symbol-font\n\t\toverlay: \n\tmagic-m15-planeswalker:\n\t\ttext box mana symbols: magic-mana-small.mse-symbol-font\n\t\toverlay: \n\tmagic-m15-planeswalker-promo-black:\n\t\ttext box mana symbols: magic-mana-small.mse-symbol-font\n\t\toverlay: \n\tmagic-m15-promo-dka:\n\t\ttext box mana symbols: magic-mana-small.mse-symbol-font\n\t\toverlay: \n\tmagic-m15-token-clear:\n\t\ttext box mana symbols: magic-mana-small.mse-symbol-font\n\t\toverlay: \n\tmagic-new-planeswalker:\n\t\ttext box mana symbols: magic-mana-small.mse-symbol-font\n\t\toverlay: \n\tmagic-new-planeswalker-4abil:\n\t\ttext box mana symbols: magic-mana-small.mse-symbol-font\n\t\toverlay: \n\tmagic-new-planeswalker-clear:\n\t\ttext box mana symbols: magic-mana-small.mse-symbol-font\n\t\toverlay: \n\tmagic-new-planeswalker-promo-black:\n\t\ttext box mana symbols: magic-mana-small.mse-symbol-font\n\t\toverlay: \n' + # separators cardsep = config.cardsep fieldsep = config.fieldsep