예제 #1
0
def prep_mana_symbols():
    if ManaSymbolModel.all():
        return
    for cc in [comb for comb in ALL_COLOR_COMBINATIONS if len(comb) <= 2]:
        for b in (True, False):
            ms = ManaSymbolModel()
            ms.phyrexian = b
            for c in cc:
                setattr(ms, c, True)
            ms.insert(commit=False)

    colorless = ManaSymbolModel()
    colorless.insert(commit=False)

    for label in ('x', 'y', 'z'):
        x_cost = ManaSymbolModel()
        x_cost.x = True
        x_cost.value = 0
        x_cost.label = label
        x_cost.insert(commit=False)
    db.Session.commit()
예제 #2
0
def do_data_process(*sets):
    print "Beginning card process..."
    CARD_DATA = get_card_data(*sets)
    stime = time.time()
    mtg = {}
    all_data = OrderedDict()
    mana_costs = []
    types = set()
    xtypes = []
    formats, xformats = set(), []
    rulings, xrulings = [], []
    mana_symbols = ManaSymbolModel.all()
    if not mana_symbols:
        prep_mana_symbols()
        mana_symbols = ManaSymbolModel.all()
    mana_symbol_dict = {}
    card_set_prop_map = {
        'releaseDate': 'release_date',
        'type': 'set_type'
    }

    card_prop_map = {
        'cmc': 'converted_mana_cost',
        'manaCost': 'mana_cost',
        'multiverseid': 'multiverse_id',
        'subtypes': 'subtype',
        'types': 'type',
        'names': 'transform',
    }
    transform_map = {}
    mana_cost_regx_str = r'\s*\{([\w\d/]+)\}\s*'
    mana_cost_regx = re.compile(mana_cost_regx_str)
    set_time = time.time()
    total_cards = 0
    total_sets = 0
    for set_code, set_data in CARD_DATA:
        total_sets += 1
        print 'Processing set {set_code} #{num}...'.format(set_code=set_code, num=total_sets)
        mtg[set_code] = {'set': None, 'cards': []}
        mtg[set_code]['set'] = make_instance(MtgCardSetModel, card_set_prop_map, **set_data)
        for card_dict in set_data['cards']:
            total_cards += 1
            # flags for logging
            cl_hybrid = False
            phy = False

            cost = {}
            if 'manaCost' not in card_dict:
                # defaults all costs to zero
                mana_cost = ManaCostModel()
                symbol = mana_symbol_dict.setdefault('c', ManaSymbolModel.get_or_make(x=False,
                                                                                      phyrexian=False,
                                                                                      **{k:(False if k != 'c' else True) for k in COLORS}))
                mana_cost.count = 0
                mana_symbol_id = symbol.id
            else:
                raw_mana_cost = card_dict.pop('manaCost')
                # token = {4} or {g/w} or {r} etc...
                for token in mana_cost_regx.findall(raw_mana_cost):
                    if token.isdigit():
                        symbol = mana_symbol_dict.setdefault('c', ManaSymbolModel.get_or_make(x=False,
                                                                                              phyrexian=False,
                                                                                              **{k:(False if k != 'c' else True) for k in COLORS}))
                        current = cost.setdefault(symbol, 0)
                        cost[symbol] = current + int(token)
                    elif token.lower() in ('x', 'y', 'z'): # Ultimate Nightmare of Wizard's of the Coast Customer Service :\
                        symbol = mana_symbol_dict.setdefault(ManaSymbol(x=True, label=token.lower()).symbol(),
                                                             ManaSymbolModel.get_or_make(x=True, label=token.lower()))
                        current = cost.setdefault(symbol, 0)
                        cost[symbol] += 1
                    else:
                        parts = token.split('/')
                        is_phy = ('P' in parts) or ('p' in parts)
                        colors = [c.lower() for c in parts if c.lower() != 'p' and not c.isdigit()]
                        colorless_pieces = [int(num) for num in parts if num.isdigit()]
                        if colorless_pieces:
                            cl_hybrid = True
                            value = colorless_pieces[0]
                            colors.append('c')
                        elif [half_cost for half_cost in parts if half_cost.lower().find('h') != -1]:
                            # if any of these "colors" have 'h' in them, they're a half-mana from Unhinged :(
                            value = .5
                            colors = [color[-1] for color in colors]
                        else:
                            value = 1
                        if is_phy:
                            phy = True
                        symbol = mana_symbol_dict.setdefault(ManaSymbol(colors=colors, phyrexian=is_phy, value=value).symbol(),
                                                             ManaSymbolModel.get_or_make(phyrexian=is_phy, value=value, **{c.lower(): (True if c in colors else False) for c in COLORS}))
                        current = cost.setdefault(symbol, 0)
                        cost[symbol] += symbol.value
            if cl_hybrid:
                print '{name} ({mid}) has hybrid colorless/colored mana! Weird!'.format(name=card_dict['name'], mid=card_dict.get('multiverseid'))
            if phy:
                print '{name} ({mid}) is phyrexian!'.format(name=card_dict['name'], mid=card_dict.get('multiverseid'))

            if not card_dict.get('colors'):
                colors = None
            else:
                colors = [Color(c) for c in card_dict.pop('colors')]
                colors = sorted([c.abbreviation for c in colors])
                colors = '/'.join(colors)

            try:
                raw_power = card_dict.pop('power')
                power = float(raw_power)
            except ValueError:
                power = 0
            except KeyError:
                raw_power = None
                power = None
            try:
                raw_toughness = card_dict.pop('toughness')
                toughness = float(raw_toughness)
            except ValueError:
                toughness = 0
            except KeyError:
                raw_toughness = None
                toughness = None

            card = make_instance(MtgCardModel,
                                 card_prop_map,
                                 toughness=toughness,
                                 power=power,
                                 raw_power=raw_power,
                                 raw_toughness=raw_toughness,
                                 colors=colors,
                                 set_id=mtg[set_code]['set'].id,
                                 **card_dict)

            for ruling_data in card_dict.get('rulings', []):
                r = RulingModel()
                r.date = ruling_data['date']
                r.ruling = ruling_data['text']
                xr = XCardRuling()
                xr.card_name = card.name
                xr.ruling_id = r.id
                rulings.append(r)
                xrulings.append(xr)


            for format_name, format_legality in card_dict.get('legalities', {}).iteritems():
                if format_legality.lower() == 'legal':
                    format_model = FormatModel.get_or_make(name=format_name)
                    # TODO: RELATE CARD NAME AND FORMAT ID IN XCARDFORMAT, LIKEWISE FOR RULINGS
                    xformat = XCardFormat()
                    xformat.format_id = format_model.id
                    xformat.card_name = card.name
                    formats.add(format_model)
                    xformats.append(xformat)

            # types and mana costs are dissociated from the actual card now, so process after
            for type_type in (('types', TypeModel, XCardType), ('subtypes', SubtypeModel, XCardSubtype)):
                type_str, type_cls, x_cls = type_type
                if card_dict.get(type_str):
                    lowercase_types = [t.lower() for t in card_dict.pop(type_str)]
                    for i, t in enumerate(lowercase_types):
                        # create/make the type instance
                        instance = type_cls.get_or_make(name=t)
                        x_thing = x_cls()
                        x_thing.card_id = card.id
                        x_thing.priority = i
                        if type_str == 'types':
                            x_thing.type_id = instance.id
                        else:
                            x_thing.subtype_id = instance.id
                        types.add(instance)
                        xtypes.append(x_thing)


            for symbol, count in cost.iteritems():
                mana_cost = ManaCostModel()
                mana_cost.count = count
                mana_cost.mana_symbol_id = symbol.id
                mana_cost.card_id = card.id
                mana_costs.append(mana_cost)

            # it's a transform card
            if card_dict.get('layout') == 'double-faced':
                # if the other side of this card has been found already, there will be
                # an entry in transform map mapping this card's name to the model of the other side
                transform = transform_map.get(card.name)
                if transform:
                    card.transform_multiverse_id = transform.multiverse_id
                # if the other side has not been found, make an entry in transform_map, the cards
                # will be linked once the other card is found
                else:
                    transform_name = [name for name in card_dict['names'] if name != card_dict['name']][0]
                    transform_map[transform_name] = card
            mtg[set_code]['cards'].append(card)
        print 'Set completed, took {duration} seconds to process'.format(duration=time.time()-set_time)
        set_time = time.time()
        total_time = time.time() - stime
    print 'Processing done, total time {total_time} seconds to process {total_sets} sets and {total_cards} cards.'.format(**locals())
    return mtg, mana_costs, list(types), xtypes, rulings, xrulings, list(formats), xformats