def caching_magic_parser(what, text): if (what, text) in g_ruleCache: return g_ruleCache[(what, text)] from MagicParser import magic_parser g_ruleCache[(what,text)] = magic_parser(what, text) return g_ruleCache[(what,text)]
def parseOracle(f): n = 0 state = 0 card = Card() rules = "" for line in f: #line = line.decode("utf8") n += 1 if state == 0: if line.startswith("Name:"): card.name = line[len("Name:"):].strip() state = 1 elif line.strip() == "": pass else: raise Exception("Expecting 'Name:' on line %d" % n) elif state == 1: if line.startswith("Cost:"): card.cost = line[len("Cost:"):].strip() state = 2 else: raise Exception("Expecting 'Cost:' on line %d" % n) elif state == 2: if line.startswith("Type:"): types = line[len("Type:"):].strip().lower().replace("’", "'") if "—" in types: types, subtypes = types.split("—", 1) typesSplit = types.split() if len(typesSplit) == 1: card.types = set([typesSplit[0]]) elif len(typesSplit) == 2: if typesSplit[0] == "artifact" and typesSplit[1] == "creature": card.types = set(typesSplit) else: card.supertypes = set([typesSplit[0]]) card.types = set([typesSplit[1]]) # multi-word subtypes (e.g. Urza's Power-Plant) subtypes = subtypes.strip() parsedSubType = magic_parser("creatureType", subtypes) if parsedSubType != None: card.subtypes = set([parsedSubType]) else: card.subtypes = set(subtypes.split()) else: card.types = set(types.split()) state = 3 else: raise Exception("Expecting 'Type:' on line %d" % n) elif state == 3: if line.startswith("Pow/Tgh:"): pt = line[len("Pow/Tgh:"):].strip() if pt == "": card.power = None card.toughness = None else: if pt[0] != "(": raise Exception("Expecting '(' on line %d" % n) if pt[-1] != ")": raise Exception("Expecting ')' on line %d" % n) power, toughness = pt[1:-1].split("/") card.power = power card.toughness = toughness state = 4 else: raise Exception("Expecting 'Pow/Tgh:' on line %d" % n) elif state == 4: if line.startswith("Rules Text:"): rules = line[len("Rules Text:"):].strip() state = 5 else: raise Exception("Expecting 'Rules Text:' on line %d" % n) elif state == 5: if line.startswith("Set/Rarity:"): card.rules = rules sets = line[len("Set/Rarity:"):] card.sets = set(map(lambda x:x.strip(), sets.split(","))) state = 6 else: rules += "\n" + line.strip() elif state == 6: if line.strip() == "": state = 0 yield card card = Card() else: card.sets = card.sets.union(set(map(lambda x:x.strip(), line.split(","))))