diff --git a/Icons/0-mana.png b/Icons/0-mana.png deleted file mode 100755 index 9dda72d..0000000 Binary files a/Icons/0-mana.png and /dev/null differ diff --git a/Icons/1-mana.png b/Icons/1-mana.png deleted file mode 100755 index 12b0d64..0000000 Binary files a/Icons/1-mana.png and /dev/null differ diff --git a/Icons/10-mana.png b/Icons/10-mana.png deleted file mode 100755 index 3254473..0000000 Binary files a/Icons/10-mana.png and /dev/null differ diff --git a/Icons/11-mana.png b/Icons/11-mana.png deleted file mode 100755 index 2938a8f..0000000 Binary files a/Icons/11-mana.png and /dev/null differ diff --git a/Icons/12-mana.png b/Icons/12-mana.png deleted file mode 100755 index 6300ebb..0000000 Binary files a/Icons/12-mana.png and /dev/null differ diff --git a/Icons/13-mana.png b/Icons/13-mana.png deleted file mode 100755 index 640add6..0000000 Binary files a/Icons/13-mana.png and /dev/null differ diff --git a/Icons/14-mana.png b/Icons/14-mana.png deleted file mode 100755 index b9188b3..0000000 Binary files a/Icons/14-mana.png and /dev/null differ diff --git a/Icons/15-mana.png b/Icons/15-mana.png deleted file mode 100755 index 6c496ed..0000000 Binary files a/Icons/15-mana.png and /dev/null differ diff --git a/Icons/16-mana.png b/Icons/16-mana.png deleted file mode 100755 index f591218..0000000 Binary files a/Icons/16-mana.png and /dev/null differ diff --git a/Icons/17-mana.png b/Icons/17-mana.png deleted file mode 100755 index 06ead76..0000000 Binary files a/Icons/17-mana.png and /dev/null differ diff --git a/Icons/18-mana.png b/Icons/18-mana.png deleted file mode 100755 index aa7f74f..0000000 Binary files a/Icons/18-mana.png and /dev/null differ diff --git a/Icons/19-mana.png b/Icons/19-mana.png deleted file mode 100755 index d00dd77..0000000 Binary files a/Icons/19-mana.png and /dev/null differ diff --git a/Icons/2-mana.png b/Icons/2-mana.png deleted file mode 100755 index 5846b44..0000000 Binary files a/Icons/2-mana.png and /dev/null differ diff --git a/Icons/20-mana.png b/Icons/20-mana.png deleted file mode 100755 index 9489419..0000000 Binary files a/Icons/20-mana.png and /dev/null differ diff --git a/Icons/3-mana.png b/Icons/3-mana.png deleted file mode 100755 index 489f610..0000000 Binary files a/Icons/3-mana.png and /dev/null differ diff --git a/Icons/4-mana.png b/Icons/4-mana.png deleted file mode 100755 index cbc3ca1..0000000 Binary files a/Icons/4-mana.png and /dev/null differ diff --git a/Icons/5-mana.png b/Icons/5-mana.png deleted file mode 100755 index b1651c9..0000000 Binary files a/Icons/5-mana.png and /dev/null differ diff --git a/Icons/6-mana.png b/Icons/6-mana.png deleted file mode 100755 index 52b6b1b..0000000 Binary files a/Icons/6-mana.png and /dev/null differ diff --git a/Icons/7-mana.png b/Icons/7-mana.png deleted file mode 100755 index fd406d7..0000000 Binary files a/Icons/7-mana.png and /dev/null differ diff --git a/Icons/8-mana.png b/Icons/8-mana.png deleted file mode 100755 index d35d0bb..0000000 Binary files a/Icons/8-mana.png and /dev/null differ diff --git a/Icons/9-mana.png b/Icons/9-mana.png deleted file mode 100755 index 57d8387..0000000 Binary files a/Icons/9-mana.png and /dev/null differ diff --git a/Icons/B-2-mana.png b/Icons/B-2-mana.png deleted file mode 100755 index f8e7f99..0000000 Binary files a/Icons/B-2-mana.png and /dev/null differ diff --git a/Icons/B-G-mana.png b/Icons/B-G-mana.png deleted file mode 100755 index f2c0d5b..0000000 Binary files a/Icons/B-G-mana.png and /dev/null differ diff --git a/Icons/B-P-mana.png b/Icons/B-P-mana.png deleted file mode 100755 index fd4aee4..0000000 Binary files a/Icons/B-P-mana.png and /dev/null differ diff --git a/Icons/B-R-mana.png b/Icons/B-R-mana.png deleted file mode 100755 index 071648e..0000000 Binary files a/Icons/B-R-mana.png and /dev/null differ diff --git a/Icons/B-mana.png b/Icons/B-mana.png deleted file mode 100755 index 6b1acbf..0000000 Binary files a/Icons/B-mana.png and /dev/null differ diff --git a/Icons/G-2-mana.png b/Icons/G-2-mana.png deleted file mode 100755 index c794056..0000000 Binary files a/Icons/G-2-mana.png and /dev/null differ diff --git a/Icons/G-P-mana.png b/Icons/G-P-mana.png deleted file mode 100755 index e66eb3b..0000000 Binary files a/Icons/G-P-mana.png and /dev/null differ diff --git a/Icons/G-U-mana.png b/Icons/G-U-mana.png deleted file mode 100755 index a606055..0000000 Binary files a/Icons/G-U-mana.png and /dev/null differ diff --git a/Icons/G-W-mana.png b/Icons/G-W-mana.png deleted file mode 100755 index 56f748d..0000000 Binary files a/Icons/G-W-mana.png and /dev/null differ diff --git a/Icons/G-mana.png b/Icons/G-mana.png deleted file mode 100755 index a2925b7..0000000 Binary files a/Icons/G-mana.png and /dev/null differ diff --git a/Icons/I-mana.png b/Icons/I-mana.png deleted file mode 100755 index 77a65cf..0000000 Binary files a/Icons/I-mana.png and /dev/null differ diff --git a/Icons/Q-symbol.png b/Icons/Q-symbol.png deleted file mode 100755 index 9006ecd..0000000 Binary files a/Icons/Q-symbol.png and /dev/null differ diff --git a/Icons/R-2-mana.png b/Icons/R-2-mana.png deleted file mode 100755 index f69a07d..0000000 Binary files a/Icons/R-2-mana.png and /dev/null differ diff --git a/Icons/R-G-mana.png b/Icons/R-G-mana.png deleted file mode 100755 index 0c36f79..0000000 Binary files a/Icons/R-G-mana.png and /dev/null differ diff --git a/Icons/R-P-mana.png b/Icons/R-P-mana.png deleted file mode 100755 index 90f0dcd..0000000 Binary files a/Icons/R-P-mana.png and /dev/null differ diff --git a/Icons/R-W-mana.png b/Icons/R-W-mana.png deleted file mode 100755 index da14dba..0000000 Binary files a/Icons/R-W-mana.png and /dev/null differ diff --git a/Icons/R-mana.png b/Icons/R-mana.png deleted file mode 100755 index fbb499d..0000000 Binary files a/Icons/R-mana.png and /dev/null differ diff --git a/Icons/S-mana.png b/Icons/S-mana.png deleted file mode 100755 index 681003b..0000000 Binary files a/Icons/S-mana.png and /dev/null differ diff --git a/Icons/T-symbol.png b/Icons/T-symbol.png deleted file mode 100755 index 0ad0e82..0000000 Binary files a/Icons/T-symbol.png and /dev/null differ diff --git a/Icons/Thumbs.db b/Icons/Thumbs.db deleted file mode 100755 index 2f803fb..0000000 Binary files a/Icons/Thumbs.db and /dev/null differ diff --git a/Icons/U-2-mana.png b/Icons/U-2-mana.png deleted file mode 100755 index cde1756..0000000 Binary files a/Icons/U-2-mana.png and /dev/null differ diff --git a/Icons/U-B-mana.png b/Icons/U-B-mana.png deleted file mode 100755 index 8e4ad19..0000000 Binary files a/Icons/U-B-mana.png and /dev/null differ diff --git a/Icons/U-P-mana.png b/Icons/U-P-mana.png deleted file mode 100755 index 5473151..0000000 Binary files a/Icons/U-P-mana.png and /dev/null differ diff --git a/Icons/U-R-mana.png b/Icons/U-R-mana.png deleted file mode 100755 index 83965c0..0000000 Binary files a/Icons/U-R-mana.png and /dev/null differ diff --git a/Icons/U-mana.png b/Icons/U-mana.png deleted file mode 100755 index a57b225..0000000 Binary files a/Icons/U-mana.png and /dev/null differ diff --git a/Icons/W-2-mana.png b/Icons/W-2-mana.png deleted file mode 100755 index 44a0238..0000000 Binary files a/Icons/W-2-mana.png and /dev/null differ diff --git a/Icons/W-B-mana.png b/Icons/W-B-mana.png deleted file mode 100755 index ec30e70..0000000 Binary files a/Icons/W-B-mana.png and /dev/null differ diff --git a/Icons/W-P-mana.png b/Icons/W-P-mana.png deleted file mode 100755 index c0ef45c..0000000 Binary files a/Icons/W-P-mana.png and /dev/null differ diff --git a/Icons/W-U-mana.png b/Icons/W-U-mana.png deleted file mode 100755 index 5d18cf2..0000000 Binary files a/Icons/W-U-mana.png and /dev/null differ diff --git a/Icons/W-mana.png b/Icons/W-mana.png deleted file mode 100755 index d534442..0000000 Binary files a/Icons/W-mana.png and /dev/null differ diff --git a/Icons/X-mana.png b/Icons/X-mana.png deleted file mode 100755 index 6882f49..0000000 Binary files a/Icons/X-mana.png and /dev/null differ diff --git a/Icons/Y-mana.png b/Icons/Y-mana.png deleted file mode 100755 index 3cdec50..0000000 Binary files a/Icons/Y-mana.png and /dev/null differ diff --git a/Icons/chaos-symbol.png b/Icons/chaos-symbol.png deleted file mode 100755 index 7fc2f3c..0000000 Binary files a/Icons/chaos-symbol.png and /dev/null differ diff --git a/decode.py b/decode.py index 5149e44..67bc364 100755 --- a/decode.py +++ b/decode.py @@ -15,95 +15,35 @@ from namediff import Namediff def exclude_sets(cardset): return cardset == 'Unglued' or cardset == 'Unhinged' or cardset == 'Celebration' -def main(fname, oname = None, verbose = True, +def main(fname, oname = None, verbose = True, encoding = 'std', gatherer = False, for_forum = False, for_mse = False, - creativity = False, norarity = False, vdump = False, for_html = False): - cards = [] - valid = 0 - invalid = 0 - unparsed = 0 + creativity = False, vdump = False, for_html = False): - if norarity: - decode_fields = [ - cardlib.field_name, - cardlib.field_supertypes, - cardlib.field_types, - cardlib.field_loyalty, - cardlib.field_subtypes, - #cardlib.field_rarity, - cardlib.field_pt, - cardlib.field_cost, - cardlib.field_text, - ] + fmt_ordered = cardlib.fmt_ordered_default + + if encoding in ['std']: + pass + elif encoding in ['named']: + fmt_ordered = cardlib.fmt_ordered_named + elif encoding in ['noname']: + fmt_ordered = cardlib.fmt_ordered_noname + elif encoding in ['rfields']: + pass + elif encoding in ['old']: + fmt_ordered = cardlib.fmt_ordered_old + elif encoding in ['norarity']: + fmt_ordered = cardlib.fmt_ordered_norarity + elif encoding in ['vec']: + pass + elif encoding in ['custom']: + ## put custom format decisions here ########################## + + ## end of custom format ###################################### + pass else: - decode_fields = cardlib.fmt_ordered_default + raise ValueError('encode.py: unknown encoding: ' + encoding) - if fname[-5:] == '.json': - if verbose: - print 'This looks like a json file: ' + fname - json_srcs = jdecode.mtg_open_json(fname, verbose) - for json_cardname in sorted(json_srcs): - if len(json_srcs[json_cardname]) > 0: - jcards = json_srcs[json_cardname] - - # look for a normal rarity version, in a set we can use - idx = 0 - card = cardlib.Card(jcards[idx], fmt_ordered = decode_fields) - while (idx < len(jcards) - and (card.rarity == utils.rarity_special_marker - or exclude_sets(jcards[idx][utils.json_field_set_name]))): - idx += 1 - if idx < len(jcards): - card = cardlib.Card(jcards[idx], fmt_ordered = decode_fields) - # if there isn't one, settle with index 0 - if idx >= len(jcards): - idx = 0 - card = cardlib.Card(jcards[idx], fmt_ordered = decode_fields) - # we could go back and look for a card satisfying one of the criteria, - # but eh - - if card.valid: - valid += 1 - elif card.parsed: - invalid += 1 - else: - unparsed += 1 - cards += [card] - - # fall back to opening a normal encoded file - else: - if verbose: - print 'Opening encoded card file: ' + fname - with open(fname, 'rt') as f: - text = f.read() - for card_src in text.split(utils.cardsep): - if card_src: - card = cardlib.Card(card_src, fmt_ordered = decode_fields) - if card.valid: - valid += 1 - elif card.parsed: - invalid += 1 - else: - unparsed += 1 - cards += [card] - - if verbose: - print (str(valid) + ' valid, ' + str(invalid) + ' invalid, ' - + str(unparsed) + ' failed to parse.') - - good_count = 0 - bad_count = 0 - for card in cards: - if not card.parsed and not card.text.text: - bad_count += 1 - else: - good_count += 1 - if good_count + bad_count > 15: - break - # random heuristic - if bad_count > 10: - print 'Saw a bunch of unparsed cards with no text:' - print 'If this is a legacy format, try rerunning with --norarity' + cards = jdecode.mtg_open_file(fname, verbose=verbose, fmt_ordered=fmt_ordered) if creativity: cbow = CBOW() @@ -113,11 +53,11 @@ def main(fname, oname = None, verbose = True, if for_mse: # have to prepend a massive chunk of formatting info writer.write(utils.mse_prepend) - + if for_html: # have to preapend html info - writer.write(utils.html_preapend) - + writer.write(utils.html_prepend) + for card in cards: if for_mse: writer.write(card.to_mse().encode('utf-8')) @@ -128,7 +68,7 @@ def main(fname, oname = None, verbose = True, fstring += 'raw:\n' + card.raw + '\n' fstring += '\n' fstring += card.format(gatherer = gatherer, for_forum = for_forum, - vdump = vdump, for_html = for_html) + vdump = vdump) fstring = fstring.replace('<', '(').replace('>', ')') writer.write(('\n' + fstring[:-1]).replace('\n', '\n\t\t')) else: @@ -160,12 +100,15 @@ def main(fname, oname = None, verbose = True, if for_mse: # more formatting info writer.write('version control:\n\ttype: none\napprentice code: ') - if for_html: # closing the html file - writer.write(utils.html_postapend) + writer.write(utils.html_append) if oname: + if for_html: + print oname + # if ('.html' != oname[-]) + # oname += '.html' if verbose: print 'Writing output to: ' + oname with open(oname, 'w') as ofile: @@ -186,8 +129,6 @@ def main(fname, oname = None, verbose = True, print 'Made an MSE set file called ' + oname + '.mse-set.' # The set file is useless outside the .mse-set, delete it. os.remove('set') - if for_html: - ## not sure what to put here else: writecards(sys.stdout) sys.stdout.flush() @@ -201,6 +142,10 @@ if __name__ == '__main__': help='encoded card file or json corpus to encode') parser.add_argument('outfile', nargs='?', default=None, help='output file, defaults to stdout') + parser.add_argument('-e', '--encoding', default='std', choices=utils.formats, + #help='{' + ','.join(formats) + '}', + help='encoding format to use', + ) parser.add_argument('-g', '--gatherer', action='store_true', help='emulate Gatherer visual spoiler') parser.add_argument('-f', '--forum', action='store_true', @@ -209,16 +154,13 @@ if __name__ == '__main__': help='use CBOW fuzzy matching to check creativity of cards') parser.add_argument('-d', '--dump', action='store_true', help='dump out lots of information about invalid cards') - parser.add_argument('--norarity', action='store_true', - 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', + parser.add_argument('-mse', '--mse', action='store_true', help='use Magic Set Editor 2 encoding; will output as .mse-set file') parser.add_argument('-html', '--html', action='store_true', help='create a .html file with pretty forum formatting') - args = parser.parse_args() - main(args.infile, args.outfile, verbose = args.verbose, + main(args.infile, args.outfile, verbose = args.verbose, encoding = args.encoding, gatherer = args.gatherer, for_forum = args.forum, for_mse = args.mse, - creativity = args.creativity, norarity = args.norarity, vdump = args.dump, for_html = args.for_html) + creativity = args.creativity, vdump = args.dump, for_html = args.html) exit(0) diff --git a/encode.py b/encode.py index da8520f..e2996f8 100755 --- a/encode.py +++ b/encode.py @@ -10,131 +10,55 @@ import utils import jdecode import cardlib -def exclude_sets(cardset): - return cardset == 'Unglued' or cardset == 'Unhinged' or cardset == 'Celebration' - -def exclude_types(cardtype): - return cardtype in ['conspiracy'] - -def exclude_layouts(layout): - return layout in ['token', 'plane', 'scheme', 'phenomenon', 'vanguard'] - -def main(fname, oname = None, verbose = True, dupes = 0, encoding = 'std', stable = False): +def main(fname, oname = None, verbose = True, encoding = 'std', + nolinetrans = False, randomize = False, nolabel = False, stable = False): fmt_ordered = cardlib.fmt_ordered_default - fmt_labeled = None + fmt_labeled = None if nolabel else cardlib.fmt_labeled_default fieldsep = utils.fieldsep + line_transformations = not nolinetrans randomize_fields = False - randomize_mana = False + randomize_mana = randomize initial_sep = True final_sep = True # set the properties of the encoding - if encoding in ['vec']: + + if encoding in ['std']: pass - elif encoding in ['std']: - if dupes == 0: - dupes = 1 - elif encoding in ['rmana']: - if dupes == 0: - dupes = 1 - randomize_mana = True - elif encoding in ['rmana_dual']: - if dupes == 0: - dupes = 1 - fmt_ordered = fmt_ordered + [cardlib.field_cost] - randomize_mana = True + elif encoding in ['named']: + fmt_ordered = cardlib.fmt_ordered_named + elif encoding in ['noname']: + fmt_ordered = cardlib.fmt_ordered_noname elif encoding in ['rfields']: - if dupes == 0: - dupes = 1 - fmt_labeled = cardlib.fmt_labeled_default randomize_fields = True - #randomize_mana = True final_sep = False + elif encoding in ['old']: + fmt_ordered = cardlib.fmt_ordered_old + elif encoding in ['norarity']: + fmt_ordered = cardlib.fmt_ordered_norarity + elif encoding in ['vec']: + pass + elif encoding in ['custom']: + ## put custom format decisions here ########################## + + ## end of custom format ###################################### + pass else: raise ValueError('encode.py: unknown encoding: ' + encoding) - if dupes <= 0: - dupes = 1 - if verbose: print 'Preparing to encode:' print ' Using encoding ' + repr(encoding) - if dupes > 1: - print ' Duplicating each card ' + str(dupes) + ' times.' if stable: print ' NOT randomizing order of cards.' - + if randomize_mana: + print ' Randomizing order of symobls in manacosts.' + if not fmt_labeled: + print ' NOT labeling fields for this run (may be harder to decode).' + if not line_transformations: + print ' NOT using line reordering transformations' - cards = [] - valid = 0 - skipped = 0 - invalid = 0 - unparsed = 0 - - if fname[-5:] == '.json': - if verbose: - print 'This looks like a json file: ' + fname - json_srcs = jdecode.mtg_open_json(fname, verbose) - # don't worry we randomize later - for json_cardname in sorted(json_srcs): - if len(json_srcs[json_cardname]) > 0: - jcards = json_srcs[json_cardname] - - # look for a normal rarity version, in a set we can use - idx = 0 - card = cardlib.Card(jcards[idx]) - while (idx < len(jcards) - and (card.rarity == utils.rarity_special_marker - or exclude_sets(jcards[idx][utils.json_field_set_name]))): - idx += 1 - if idx < len(jcards): - card = cardlib.Card(jcards[idx]) - # if there isn't one, settle with index 0 - if idx >= len(jcards): - idx = 0 - card = cardlib.Card(jcards[idx]) - # we could go back and look for a card satisfying one of the criteria, - # but eh - - skip = False - if (exclude_sets(jcards[idx][utils.json_field_set_name]) - or exclude_layouts(jcards[idx]['layout'])): - skip = True - for cardtype in card.types: - if exclude_types(cardtype): - skip = True - if skip: - skipped += 1 - continue - - if card.valid: - valid += 1 - cards += [card] * dupes - elif card.parsed: - invalid += 1 - else: - unparsed += 1 - - # fall back to opening a normal encoded file - else: - if verbose: - print 'Opening encoded card file: ' + fname - with open(fname, 'rt') as f: - text = f.read() - for card_src in text.split(utils.cardsep): - if card_src: - card = cardlib.Card(card_src) - if card.valid: - valid += 1 - cards += [card] * dupes - elif card.parsed: - invalid += 1 - else: - unparsed += 1 - - if verbose: - print (str(valid) + ' valid, ' + str(skipped) + ' skipped, ' - + str(invalid) + ' invalid, ' + str(unparsed) + ' failed to parse.') + cards = jdecode.mtg_open_file(fname, verbose=verbose, linetrans=line_transformations) # This should give a random but consistent ordering, to make comparing changes # between the output of different versions easier. @@ -174,17 +98,23 @@ if __name__ == '__main__': help='encoded card file or json corpus to encode') parser.add_argument('outfile', nargs='?', default=None, help='output file, defaults to stdout') - parser.add_argument('-d', '--duplicate', metavar='N', type=int, default=0, - help='number of times to duplicate each card') - parser.add_argument('-e', '--encoding', default='std', - choices=['std', 'rmana', 'rmana_dual', 'rfields', 'vec']) + parser.add_argument('-e', '--encoding', default='std', choices=utils.formats, + #help='{' + ','.join(formats) + '}', + help='encoding format to use', + ) + parser.add_argument('-r', '--randomize', action='store_true', + help='randomize the order of symbols in mana costs') + parser.add_argument('--nolinetrans', action='store_true', + help="don't reorder lines of card text") + parser.add_argument('--nolabel', action='store_true', + help="don't label fields") parser.add_argument('-s', '--stable', action='store_true', help="don't randomize the order of the cards") parser.add_argument('-v', '--verbose', action='store_true', help='verbose output') args = parser.parse_args() - main(args.infile, args.outfile, verbose = args.verbose, dupes = args.duplicate, - encoding = args.encoding, stable = args.stable) + main(args.infile, args.outfile, verbose = args.verbose, encoding = args.encoding, + nolinetrans = args.nolinetrans, randomize = args.randomize, nolabel = args.nolabel, + stable = args.stable) exit(0) - diff --git a/lib/cardlib.py b/lib/cardlib.py index 75dca7f..c452285 100644 --- a/lib/cardlib.py +++ b/lib/cardlib.py @@ -88,7 +88,8 @@ fieldnames = [ field_text, ] -fmt_ordered_default = [ +# legacy +fmt_ordered_old = [ field_name, field_supertypes, field_types, @@ -99,6 +100,52 @@ fmt_ordered_default = [ field_cost, field_text, ] +fmt_ordered_norarity = [ + field_name, + field_supertypes, + field_types, + field_loyalty, + field_subtypes, + field_pt, + field_cost, + field_text, +] + +# standard +fmt_ordered_default = [ + field_types, + field_supertypes, + field_subtypes, + field_loyalty, + field_pt, + field_text, + field_cost, + field_rarity, + field_name, +] + +# minor variations +fmt_ordered_noname = [ + field_types, + field_supertypes, + field_subtypes, + field_loyalty, + field_pt, + field_text, + field_cost, + field_rarity, +] +fmt_ordered_named = [ + field_name, + field_types, + field_supertypes, + field_subtypes, + field_loyalty, + field_pt, + field_text, + field_cost, + field_rarity, +] fmt_labeled_default = { field_name : field_label_name, @@ -176,7 +223,7 @@ def fields_check_valid(fields): # releaseDate - string # starter - boolean -def fields_from_json(src_json): +def fields_from_json(src_json, linetrans = True): parsed = True valid = True fields = {} @@ -254,6 +301,8 @@ def fields_from_json(src_json): text_val = transforms.text_pass_8_equip(text_val) text_val = transforms.text_pass_9_newlines(text_val) text_val = transforms.text_pass_10_symbols(text_val) + if linetrans: + text_val = transforms.text_pass_11_linetrans(text_val) text_val = utils.to_ascii(text_val) text_val = text_val.strip() mtext = Manatext(text_val, fmt = 'json') @@ -340,9 +389,7 @@ def fields_from_format(src_text, fmt_ordered, fmt_labeled, fieldsep): class Card: '''card representation with data''' - def __init__(self, src, fmt_ordered = fmt_ordered_default, - fmt_labeled = fmt_labeled_default, - fieldsep = utils.fieldsep): + def __init__(self, src, fmt_ordered = fmt_ordered_default, fmt_labeled = fmt_labeled_default, fieldsep = utils.fieldsep, linetrans = True): # source fields, exactly one will be set self.json = None self.raw = None @@ -378,8 +425,9 @@ class Card: self.bside = Card(src[utils.json_field_bside], fmt_ordered = fmt_ordered, fmt_labeled = fmt_labeled, - fieldsep = fieldsep) - p_success, v_success, parsed_fields = fields_from_json(src) + fieldsep = fieldsep, + linetrans = linetrans) + p_success, v_success, parsed_fields = fields_from_json(src, linetrans = linetrans) self.parsed = p_success self.valid = v_success self.fields = parsed_fields @@ -391,7 +439,8 @@ class Card: self.bside = Card(utils.bsidesep.join(sides[1:]), fmt_ordered = fmt_ordered, fmt_labeled = fmt_labeled, - fieldsep = fieldsep) + fieldsep = fieldsep, + linetrans = linetrans) p_success, v_success, parsed_fields = fields_from_format(sides[0], fmt_ordered, fmt_labeled, fieldsep) self.parsed = p_success @@ -503,10 +552,7 @@ class Card: # the NN representation, use str() or format() for output intended for human # readers. - def encode(self, fmt_ordered = fmt_ordered_default, - fmt_labeled = None, fieldsep = utils.fieldsep, - randomize_fields = False, randomize_mana = False, - initial_sep = True, final_sep = True): + def encode(self, fmt_ordered = fmt_ordered_default, fmt_labeled = None, fieldsep = utils.fieldsep, randomize_fields = False, randomize_mana = False, initial_sep = True, final_sep = True): outfields = [] for field in fmt_ordered: @@ -608,7 +654,7 @@ class Card: mtext = transforms.text_unpass_2_counters(mtext) #mtext = transforms.text_unpass_3_uncast(mtext) mtext = transforms.text_unpass_4_unary(mtext) - mtext = transforms.text_unpass_5_symbols(mtext, for_forum) + mtext = transforms.text_unpass_5_symbols(mtext, for_forum, for_html) mtext = sentencecase(mtext) mtext = transforms.text_unpass_6_cardname(mtext, cardname) mtext = transforms.text_unpass_7_newlines(mtext) @@ -638,25 +684,27 @@ class Card: outstr += '
' cardname = self.__dict__[field_name] #cardname = transforms.name_unpass_1_dashes(self.__dict__[field_name]) - outstr += "
" + cardname + "
" + if vdump and not cardname: + cardname = '_NONAME_' + outstr += cardname + ' ' + + coststr = self.__dict__[field_cost].format(for_html = for_html) + if vdump or not coststr == '_NOCOST_': + outstr += coststr + outstr += '
' + 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 += ' (' + rarity.lower() + ')' - outstr += '\n' - - # I need the simple formatting with '{' - coststr = self.__dict__[field_cost].format() - if vdump or not coststr == '_NOCOST_': - outstr += coststr.replace("/","-").replace("{",'') - outstr += '\n' + outstr += ' (' + rarity.lower() + ') ' + outstr += '\n
' - outstr += ' '.join(self.__dict__[field_supertypes] + self.__dict__[field_types]) + outstr += ' '.join(self.__dict__[field_supertypes] + self.__dict__[field_types]) if self.__dict__[field_subtypes]: outstr += ' ' + utils.dash_marker + ' ' + ' '.join(self.__dict__[field_subtypes]) - outstr += '\n' + outstr += '
\n' if self.__dict__[field_text].text: mtext = self.__dict__[field_text].text @@ -664,17 +712,17 @@ class Card: #mtext = transforms.text_unpass_2_counters(mtext) #mtext = transforms.text_unpass_3_uncast(mtext) mtext = transforms.text_unpass_4_unary(mtext) - mtext = transforms.text_unpass_5_symbols(mtext, for_forum) + mtext = transforms.text_unpass_5_symbols(mtext,for_forum, for_html) #mtext = transforms.text_unpass_6_cardname(mtext, cardname) - mtext = transforms.text_unpass_7_newlines(mtext) + mtext = transforms.text_unpass_7_newlines(mtext).replace("\n", "
") #mtext = transforms.text_unpass_8_unicode(mtext) newtext = Manatext('') newtext.text = mtext newtext.costs = self.__dict__[field_text].costs - outstr += newtext.format().replace("/","-").replace("{",'') + '\n' + outstr += newtext.format(for_html = for_html) + '\n' if self.__dict__[field_pt]: - outstr += '(' + utils.from_unary(self.__dict__[field_pt]) + ')' + outstr += '
(' + utils.from_unary(self.__dict__[field_pt]) + ')
' outstr += '\n' if self.__dict__[field_loyalty]: @@ -687,7 +735,6 @@ class Card: for idx, value in self.__dict__[field_other]: outstr += '<' + str(idx) + '> ' + str(value) outstr += '\n' - else: cardname = self.__dict__[field_name] #cardname = transforms.name_unpass_1_dashes(self.__dict__[field_name]) @@ -723,7 +770,7 @@ class Card: #mtext = transforms.text_unpass_2_counters(mtext) #mtext = transforms.text_unpass_3_uncast(mtext) mtext = transforms.text_unpass_4_unary(mtext) - mtext = transforms.text_unpass_5_symbols(mtext, for_forum) + mtext = transforms.text_unpass_5_symbols(mtext, for_forum, for_html) #mtext = transforms.text_unpass_6_cardname(mtext, cardname) mtext = transforms.text_unpass_7_newlines(mtext) #mtext = transforms.text_unpass_8_unicode(mtext) @@ -749,11 +796,12 @@ class Card: if self.bside: if for_html: - outstr += "
\n" + outstr += "

\n" else: outstr += utils.dash_marker * 8 + '\n' - outstr += self.bside.format(gatherer = gatherer, for_forum = for_forum) - + outstr += self.bside.format(gatherer = gatherer, for_forum = for_forum, for_html = for_html) + if for_html: + outstr += "
" return outstr def to_mse(self, print_raw = False, vdump = False): @@ -794,7 +842,7 @@ class Card: mtext = transforms.text_unpass_2_counters(mtext) mtext = transforms.text_unpass_3_uncast(mtext) mtext = transforms.text_unpass_4_unary(mtext) - mtext = transforms.text_unpass_5_symbols(mtext, False) + mtext = transforms.text_unpass_5_symbols(mtext, False, False) mtext = sentencecase(mtext) # I don't really want these MSE specific passes in transforms, # but they could be pulled out separately somewhere else in here. @@ -861,7 +909,7 @@ class Card: mtext2 = transforms.text_unpass_2_counters(mtext2) mtext2 = transforms.text_unpass_3_uncast(mtext2) mtext2 = transforms.text_unpass_4_unary(mtext2) - mtext2 = transforms.text_unpass_5_symbols(mtext2, False) + mtext2 = transforms.text_unpass_5_symbols(mtext2, False, False) mtext2 = sentencecase(mtext2) mtext2 = mtext2.replace(utils.this_marker, '' + utils.this_marker + '') diff --git a/lib/jdecode.py b/lib/jdecode.py index ca66f86..fa2d3f7 100644 --- a/lib/jdecode.py +++ b/lib/jdecode.py @@ -1,6 +1,7 @@ import json -import config +import utils +import cardlib def mtg_open_json(fname, verbose = False): @@ -16,7 +17,7 @@ def mtg_open_json(fname, verbose = False): setname = set['name'] for card in set['cards']: - card[config.json_field_set_name] = setname + card[utils.json_field_set_name] = setname cardnumber = None if 'number' in card: @@ -48,7 +49,7 @@ def mtg_open_json(fname, verbose = False): if aside_uid in asides: # the second check handles the brothers yamazaki edge case if not asides[aside_uid]['name'] == bsides[uid]['name']: - asides[aside_uid][config.json_field_bside] = bsides[uid] + asides[aside_uid][utils.json_field_bside] = bsides[uid] else: pass # this exposes some coldsnap theme deck bsides that aren't @@ -59,3 +60,109 @@ def mtg_open_json(fname, verbose = False): if verbose: print 'Opened ' + str(len(allcards)) + ' uniquely named cards.' return allcards + +# filters to ignore some undesirable cards, only used when opening json +def default_exclude_sets(cardset): + return cardset == 'Unglued' or cardset == 'Unhinged' or cardset == 'Celebration' + +def default_exclude_types(cardtype): + return cardtype in ['conspiracy'] + +def default_exclude_layouts(layout): + return layout in ['token', 'plane', 'scheme', 'phenomenon', 'vanguard'] + +# centralized logic for opening files of cards, either encoded or json +def mtg_open_file(fname, verbose = False, + linetrans = True, fmt_ordered = cardlib.fmt_ordered_default, + exclude_sets = default_exclude_sets, + exclude_types = default_exclude_types, + exclude_layouts = default_exclude_layouts): + + cards = [] + valid = 0 + skipped = 0 + invalid = 0 + unparsed = 0 + + if fname[-5:] == '.json': + if verbose: + print 'This looks like a json file: ' + fname + json_srcs = mtg_open_json(fname, verbose) + # sorted for stability + for json_cardname in sorted(json_srcs): + if len(json_srcs[json_cardname]) > 0: + jcards = json_srcs[json_cardname] + + # look for a normal rarity version, in a set we can use + idx = 0 + card = cardlib.Card(jcards[idx], linetrans=linetrans) + while (idx < len(jcards) + and (card.rarity == utils.rarity_special_marker + or exclude_sets(jcards[idx][utils.json_field_set_name]))): + idx += 1 + if idx < len(jcards): + card = cardlib.Card(jcards[idx], linetrans=linetrans) + # if there isn't one, settle with index 0 + if idx >= len(jcards): + idx = 0 + card = cardlib.Card(jcards[idx], linetrans=linetrans) + # we could go back and look for a card satisfying one of the criteria, + # but eh + + skip = False + if (exclude_sets(jcards[idx][utils.json_field_set_name]) + or exclude_layouts(jcards[idx]['layout'])): + skip = True + for cardtype in card.types: + if exclude_types(cardtype): + skip = True + if skip: + skipped += 1 + continue + + if card.valid: + valid += 1 + cards += [card] + elif card.parsed: + invalid += 1 + else: + unparsed += 1 + + # fall back to opening a normal encoded file + else: + if verbose: + print 'Opening encoded card file: ' + fname + with open(fname, 'rt') as f: + text = f.read() + for card_src in text.split(utils.cardsep): + if card_src: + card = cardlib.Card(card_src, fmt_ordered=fmt_ordered) + if card.valid: + valid += 1 + cards += [card] + elif card.parsed: + invalid += 1 + else: + unparsed += 1 + + if verbose: + print (str(valid) + ' valid, ' + str(skipped) + ' skipped, ' + + str(invalid) + ' invalid, ' + str(unparsed) + ' failed to parse.') + + good_count = 0 + bad_count = 0 + for card in cards: + if not card.parsed and not card.text.text: + bad_count += 1 + elif len(card.name) > 50 or len(card.rarity) > 3: + bad_count += 1 + else: + good_count += 1 + if good_count + bad_count > 15: + break + # random heuristic + if bad_count > 10: + print 'WARNING: Saw a bunch of unparsed cards:' + print ' Is this a legacy format, you may need to specify the field order.' + + return cards diff --git a/lib/manalib.py b/lib/manalib.py index 688f3f2..7875b33 100644 --- a/lib/manalib.py +++ b/lib/manalib.py @@ -108,12 +108,13 @@ class Manacost: return utils.mana_untranslate(utils.mana_open_delimiter + ''.join(self.sequence) + utils.mana_close_delimiter) - def format(self, for_forum = False): + def format(self, for_forum = False, for_html = False): if self.none: return '_NOCOST_' + else: return utils.mana_untranslate(utils.mana_open_delimiter + ''.join(self.sequence) - + utils.mana_close_delimiter, for_forum) + + utils.mana_close_delimiter, for_forum, for_html) def encode(self, randomize = False): if self.none: @@ -177,10 +178,10 @@ class Manatext: text = text.replace(utils.reserved_mana_marker, str(cost), 1) return text - def format(self, for_forum = False): + def format(self, for_forum = False, for_html = False): text = self.text for cost in self.costs: - text = text.replace(utils.reserved_mana_marker, cost.format(for_forum = for_forum), 1) + text = text.replace(utils.reserved_mana_marker, cost.format(for_forum = for_forum, for_html = for_html), 1) return text def encode(self, randomize = False): diff --git a/lib/transforms.py b/lib/transforms.py index f696150..319955c 100644 --- a/lib/transforms.py +++ b/lib/transforms.py @@ -399,13 +399,55 @@ def text_pass_8_equip(s): def text_pass_9_newlines(s): - return s.replace('\n', '\\') + return s.replace('\n', utils.newline) def text_pass_10_symbols(s): return utils.to_symbols(s) +# reorder the lines of text into a canonical form: +# first enchant and equip +# then other keywords, one per line (things with no period on the end) +# then other abilities +# then kicker and countertype last of all +def text_pass_11_linetrans(s): + # let's just not deal with level up + if 'level up' in s: + return s + + prelines = [] + keylines = [] + mainlines = [] + postlines = [] + + lines = s.split(utils.newline) + for line in lines: + if not '.' in line: + # because this is inconsistent + line = line.replace(';', ',') + sublines = line.split(',') + for subline in sublines: + if 'equip' in subline or 'enchant' in subline: + prelines += [subline.strip()] + elif 'countertype' in subline or 'kicker' in subline: + postlines += [subline.strip()] + else: + keylines += [subline.strip()] + elif u'\u2014' in line and not u' \u2014 ' in line: + if 'equip' in line or 'enchant' in line: + prelines += [line.strip()] + elif 'countertype' in line or 'kicker' in line: + postlines += [line.strip()] + else: + keylines += [line.strip()] + else: + mainlines += [line.strip()] + + alllines = prelines + keylines + mainlines + postlines + return utils.newline.join(alllines) + + # Text unpasses, for decoding. All assume the text inside a Manatext, so don't do anything # weird with the mana cost symbol. @@ -473,8 +515,8 @@ def text_unpass_4_unary(s): return utils.from_unary(s) -def text_unpass_5_symbols(s, for_forum): - return utils.from_symbols(s, for_forum = for_forum) +def text_unpass_5_symbols(s, for_forum, for_html): + return utils.from_symbols(s, for_forum = for_forum, for_html = for_html) def text_unpass_6_cardname(s, name): diff --git a/lib/utils.py b/lib/utils.py index f0063c7..81e9bb9 100644 --- a/lib/utils.py +++ b/lib/utils.py @@ -10,9 +10,20 @@ import config 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' # special chunk of text to start an HTML document. -box_height = 400 -html_preapend = "\n\n\n" -html_postapend = "" +box_height = 350 +html_prepend = "\n\n\n" +html_append = "\n/body>\n" +# encoding formats we know about +formats = [ + 'std', + 'named', + 'noname', + 'rfields', + 'old', + 'norarity', + 'vec', + 'custom', +] # separators cardsep = config.cardsep @@ -129,6 +140,9 @@ mana_json_close_delimiter = mana_close_delimiter mana_json_hybrid_delimiter = '/' mana_forum_open_delimiter = '[mana]' mana_forum_close_delimiter = '[/mana]' +mana_html_open_delimiter = "" +mana_html_hybrid_delimiter = '-' mana_unary_marker = '' # if the same as unary_marker, from_unary WILL replace numbers in mana costs mana_unary_counter = unary_counter @@ -379,7 +393,7 @@ def mana_translate(jmanastr): # convert an encoded mana string back to json mana_symlen_min = min([len(sym) for sym in mana_symall_decode]) mana_symlen_max = max([len(sym) for sym in mana_symall_decode]) -def mana_untranslate(manastr, for_forum = False): +def mana_untranslate(manastr, for_forum = False, for_html = False): inner = manastr[1:-1] jmanastr = '' colorless_total = 0 @@ -399,6 +413,12 @@ def mana_untranslate(manastr, for_forum = False): idx += symlen if for_forum: jmanastr = jmanastr + mana_decode_direct_forum(sym) + if for_html: + jmanastr = jmanastr + mana_decode_direct(sym) + jmanastr = jmanastr.replace(mana_open_delimiter, mana_html_open_delimiter) + jmanastr = jmanastr.replace(mana_close_delimiter, mana_html_close_delimiter) + jmanastr = jmanastr.replace(mana_open_delimiter, mana_html_open_delimiter) + jmanastr = jmanastr.replace(mana_json_hybrid_delimiter, mana_html_hybrid_delimiter) else: jmanastr = jmanastr + mana_decode_direct(sym) break @@ -412,6 +432,13 @@ def mana_untranslate(manastr, for_forum = False): return (mana_forum_open_delimiter + ('' if colorless_total == 0 else str(colorless_total)) + jmanastr + mana_forum_close_delimiter) + if for_html: + if jmanastr == '': + return mana_html_open_delimiter + str(colorless_total) + mana_html_close_delimiter + else: + return (mana_html_open_delimiter + ('' if colorless_total == 0 + else str(colorless_total)) + + mana_html_close_delimiter + jmanastr) else: if jmanastr == '': return mana_json_open_delimiter + str(colorless_total) + mana_json_close_delimiter @@ -457,6 +484,11 @@ symbol_forum_trans = { tap_marker : mana_forum_open_delimiter + json_symbol_tap + mana_forum_close_delimiter, untap_marker : mana_forum_open_delimiter + json_symbol_untap + mana_forum_close_delimiter, } +symbol_html_trans = { + tap_marker : mana_html_open_delimiter + json_symbol_tap + mana_html_close_delimiter, + untap_marker : mana_html_open_delimiter + json_symbol_untap + mana_html_close_delimiter, +} + json_symbol_regex = (re.escape(mana_json_open_delimiter) + '[' + json_symbol_tap + json_symbol_tap.lower() + json_symbol_untap + json_symbol_untap.lower() @@ -469,7 +501,7 @@ def to_symbols(s): s = s.replace(jsymstr, json_symbol_trans[jsymstr]) return s -def from_symbols(s, for_forum = False): +def from_symbols(s, for_forum = False, for_html = False): symstrs = re.findall(symbol_regex, s) #for symstr in sorted(symstrs, lambda x,y: cmp(len(x), len(y)), reverse = True): # We have to do the right thing here, because the thing we replace exists in the thing @@ -477,6 +509,8 @@ def from_symbols(s, for_forum = False): for symstr in set(symstrs): if for_forum: s = s.replace(symstr, symbol_forum_trans[symstr]) + elif for_html: + s = s.replace(symstr, symbol_html_trans[symstr]) else: s = s.replace(symstr, symbol_trans[symstr]) return s