def test_nonzero_autoincrement_ids(session, cls): """Check that autoincrementing ids don't contain zeroes MySQL doesn't like these, see e.g. bug #580 """ if 'id' not in cls.__table__.c: return if not cls.__table__.c.id.autoincrement: return try: util.get(session, cls, id=0) except NoResultFound: pass else: pytest.fail("No zero id in %s" % cls.__name__)
def test_markdown_string(session): en = util.get(session, tables.Language, 'en') md = markdown.MarkdownString( '[]{move:thunderbolt} [paralyzes]{mechanic:paralysis} []{form:sky shaymin}. []{pokemon:mewthree} does not exist.', session, en) assert str( md) == 'Thunderbolt paralyzes Sky Shaymin. mewthree does not exist.' assert md.as_html( ) == '<p><span>Thunderbolt</span> <span>paralyzes</span> <span>Sky Shaymin</span>. <span>mewthree</span> does not exist.</p>' class ObjectTestExtension(markdown.PokedexLinkExtension): def object_url(self, category, obj): if isinstance(obj, tables.PokemonForm): return "%s/%s %s" % (category, obj.form_identifier, obj.species.identifier) else: return "%s/%s" % (category, obj.identifier) class IdentifierTestExtension(markdown.PokedexLinkExtension): def identifier_url(self, category, ident): return "%s/%s" % (category, ident) assert md.as_html(extension=ObjectTestExtension(session)) == ( '<p><a href="move/thunderbolt">Thunderbolt</a> <span>paralyzes</span> <a href="form/sky shaymin">Sky Shaymin</a>. <span>mewthree</span> does not exist.</p>' ) assert md.as_html(extension=IdentifierTestExtension(session)) == ( '<p><a href="move/thunderbolt">Thunderbolt</a> <a href="mechanic/paralysis">paralyzes</a> <a href="form/sky shaymin">Sky Shaymin</a>. <a href="pokemon/mewthree">mewthree</a> does not exist.</p>' )
def test_types_french_order(session): french = util.get(session, tables.Language, u'fr') types = session.query(tables.Type).filter(tables.Type.id < 10000) types = list(util.order_by_name(types, tables.Type, language=french)) assert types[0].name_map[french] == 'Acier', types[0].name_map[french] # SQLite doesn't know how to sort unicode properly, so accented charaters come last. # Postgres doesn't have this problem. assert types[-1].name_map[french] in (u'Électrik', u'Vol'), types[-1].name_map[french]
def langs(self, langs): """UI language identifiers, by priority (highest first)""" self._langs = langs self.languages = [util.get(self.session, tables.Language, lang) for lang in langs] self.translator = Translator(langs) if self.mainwindow: self.mainwindow.retranslate.emit()
def test_types_french_order(session): french = util.get(session, tables.Language, 'fr') types = session.query(tables.Type).filter(tables.Type.id < 10000) types = list(util.order_by_name(types, tables.Type, language=french)) assert types[0].name_map[french] == 'Acier', types[0].name_map[french] # SQLite doesn't know how to sort unicode properly, so accented charaters come last. # Postgres doesn't have this problem. assert types[-1].name_map[french] in (u'Électrik', u'Vol'), types[-1].name_map[french]
def langs(self, langs): """UI language identifiers, by priority (highest first)""" self._langs = langs self.languages = [ util.get(self.session, tables.Language, lang) for lang in langs ] self.translator = Translator(langs) if self.mainwindow: self.mainwindow.retranslate.emit()
def results(request): session = connect() try: team_text = request.POST['text'] except: team_text = 'No team loaded' #Get the array of party Pokemon as strings pokemon_list = getPokemonList(team_text) #Get party_list, an array of tables.Pokemon party_list = [] pokemon_type_list = [] for i in range(0,len(pokemon_list)): try: party_list.append(util.get(session, tables.PokemonSpecies, name=pokemon_list[i]).default_pokemon) continue except: pass try: party_list.append(util.get(session, tables.Pokemon, pokemon_list[i].lower())) except: pass #The max resist for a certain type max_resists = [] #Get list of types as tables.Type type_query = session.query(tables.Type) for (i, type) in enumerate(type_query): if i > 17: break max_resists.append([type.name, 100]) for pokemon in party_list: resist = 1 for type in pokemon.types: resist = resist * type.target_efficacies[i].damage_factor / 100.0 if resist < max_resists[i][1]: max_resists[i][1] = resist return render(request, 'checker/results.html', {'party_list': party_list, 'max_resists': max_resists, 'team_text': team_text})
def get_illustrator(session, en, name): identifier = identifier_from_name(name) try: return util.get(session, tcg_tables.Illustrator, identifier) except NoResultFound: entity = tcg_tables.Illustrator() entity.name = name entity.identifier = identifier session.add(entity) return entity
def export_set(session, options): from ptcgdex import tcg_tables from ptcgdex import load as ptcg_load from pokedex.db import util sets = [] for set_ident in options['<set-identifier>']: sets.append(util.get(session, tcg_tables.Set, set_ident)) if options['--all']: sets = session.query(tcg_tables.Set) for tcg_set in sets: print ptcg_load.yaml_dump(ptcg_load.export_set(tcg_set)),
def get_pokemon(obj): """return a dict with keys id, name, type, abilities, stats, link, sprite, and color.""" if not obj.is_default: # if it's an alternate form link = '{name}?form={form}'.format( # don't want quote() to catch ? and = name=sanitize(obj.species.name), form=sanitize(obj.default_form.form_identifier), ) sprite = '{}-{}.png'.format(obj.species.id, obj.default_form.form_identifier.lower()) else: link = sanitize(obj.species.name) sprite = '{}.png'.format(obj.species.id) stat_names = ["hp", "atk", "def", "spatk", "spdef", "spd"] base_stats = [stat.base_stat for stat in obj.stats] stats = dict(zip(stat_names, base_stats)) # (x, y) -> {x: y} stats["bst"] = sum(base_stats) # sumo doesn't have a national dex :< if obj.species.id < 722: version = 26 else: version = 28 return { "table": "pokemon", "id": obj.species.id, "name": obj.name, "species": obj.species.genus, "type": [ptype.name for ptype in obj.types], "flavor": util.get(session, tables.PokemonSpeciesFlavorText, id=(obj.species.id, version, 9)).flavor_text.replace('\n', ' '), "abilities": [ability.name for ability in obj.abilities], "hidden": obj.hidden_ability.name if obj.hidden_ability else None, "stats": stats, "link": 'https://veekun.com/dex/pokemon/' + link, "party": 'https://veekun.com/dex/media/pokemon/icons/' + sprite, "sprite": 'https://veekun.com/dex/media/pokemon/main-sprites/ultra-sun-ultra-moon/' + sprite, "color": colors[obj.types[0].name.lower()] }
def export(session, options): from ptcgdex import tcg_tables from ptcgdex import load as ptcg_load from pokedex.db import util prints = [] for print_id in options['<print-id>']: prints.append(util.get(session, tcg_tables.Print, id=int(print_id))) if options['--all']: prints = session.query(tcg_tables.Print) for tcg_print in prints: print ptcg_load.yaml_dump(ptcg_load.export_print(tcg_print)),
def get_family(session, en, name): if name == 'Ho-oh': # Standardize Ho-Oh capitaliation name = 'Ho-Oh' # TODO try: return util.get(session, tcg_tables.CardFamily, name=name) except NoResultFound: family = tcg_tables.CardFamily() family.name_map[en] = name family.identifier = identifier_from_name(name) session.add(family) return family
def get_replacement(session, entire_text, context, matchobj): label = matchobj.group('label') category = matchobj.group('category') target = matchobj.group('target') or label try: result = manual_replacements[matchobj.group(0)] except KeyError: if category == 'mechanic': target = target.lower() target = target.replace(' ', '-') wanted_label = '' else: query = None if category == 'item': table = tables.Item elif category == 'ability': table = tables.Ability elif category == 'move': table = tables.Move elif category == 'type': table = tables.Type elif category == 'pokemon': table = tables.Pokemon elif category == 'location': table = tables.Location else: print() print(repr(entire_text)) print(repr(matchobj.group(0))) raise ValueError('Category %s not implemented' % category) try: thingy = util.get(session, table, target) wanted_label = thingy.name except: print() print(repr(entire_text)) print(repr(matchobj.group(0))) raise if wanted_label.lower() == label.lower(): result = "[]{%s:%s}" % (category, target) else: result = "[%s]{%s:%s}" % (label, category, target) if wanted_label: print() print(context) print("%-40s" % matchobj.group(0), end=' ') print('%s != %s' % (label, wanted_label)) assert result_link_re.match(result), result return result
def get_replacement(session, entire_text, context, matchobj): label = matchobj.group('label') category = matchobj.group('category') target = matchobj.group('target') or label try: result = manual_replacements[matchobj.group(0)] except KeyError: if category == 'mechanic': target = target.lower() target = target.replace(' ', '-') wanted_label = '' else: query = None if category == 'item': table = tables.Item elif category == 'ability': table = tables.Ability elif category == 'move': table = tables.Move elif category == 'type': table = tables.Type elif category == 'pokemon': table = tables.Pokemon elif category == 'location': table = tables.Location else: print print repr(entire_text) print repr(matchobj.group(0)) raise ValueError('Category %s not implemented' % category) try: thingy = util.get(session, table, target) wanted_label = thingy.name except: print print repr(entire_text) print repr(matchobj.group(0)) raise if wanted_label.lower() == label.lower(): result = "[]{%s:%s}" % (category, target) else: result = "[%s]{%s:%s}" % (label, category, target) if wanted_label: print print context print "%-40s" % matchobj.group(0), print '%s != %s' % (label, wanted_label) assert result_link_re.match(result), result return result
def tr(self, stringMap, fallbackLanguage=None): """Get an appropriate string from string_map. Falls back to fallback_language, or the game language by default, but uglifies the string if it does. """ for language in self.languages: try: return stringMap[language] except KeyError: pass if fallbackLanguage == None: fallbackLanguage = util.get(self.session, tables.Language, id=self.session.default_language_id) try: return '[%s: %s]' % ( fallbackLanguage.identifier, stringMap[fallbackLanguage], ) except KeyError: _ = self.translator return _('[translation not available]')
def test_markdown_string(session): en = util.get(session, tables.Language, 'en') md = markdown.MarkdownString('[]{move:thunderbolt} [paralyzes]{mechanic:paralysis} []{form:sky shaymin}. []{pokemon:mewthree} does not exist.', session, en) assert str(md) == 'Thunderbolt paralyzes Sky Shaymin. mewthree does not exist.' assert md.as_html() == '<p><span>Thunderbolt</span> <span>paralyzes</span> <span>Sky Shaymin</span>. <span>mewthree</span> does not exist.</p>' class ObjectTestExtension(markdown.PokedexLinkExtension): def object_url(self, category, obj): if isinstance(obj, tables.PokemonForm): return "%s/%s %s" % (category, obj.form_identifier, obj.species.identifier) else: return "%s/%s" % (category, obj.identifier) class IdentifierTestExtension(markdown.PokedexLinkExtension): def identifier_url(self, category, ident): return "%s/%s" % (category, ident) assert md.as_html(extension=ObjectTestExtension(session)) == ( '<p><a href="move/thunderbolt">Thunderbolt</a> <span>paralyzes</span> <a href="form/sky shaymin">Sky Shaymin</a>. <span>mewthree</span> does not exist.</p>') assert md.as_html(extension=IdentifierTestExtension(session)) == ( '<p><a href="move/thunderbolt">Thunderbolt</a> <a href="mechanic/paralysis">paralyzes</a> <a href="form/sky shaymin">Sky Shaymin</a>. <a href="pokemon/mewthree">mewthree</a> does not exist.</p>')
def get_pokemon(obj): """return a dict with keys id, name, type, abilities, stats, link, sprite, and color.""" if not obj.is_default: # if it's an alternate form link = '{name}?form={form}'.format( # don't want quote() to catch ? and = name = sanitize(obj.species.name), form = sanitize(obj.default_form.form_identifier), ) sprite = '{}-{}.png'.format(obj.species.id, obj.default_form.form_identifier.lower()) else: link = sanitize(obj.species.name) sprite = '{}.png'.format(obj.species.id) stat_names = ["hp", "atk", "def", "spatk", "spdef", "spd"] base_stats = [stat.base_stat for stat in obj.stats] stats = dict(zip(stat_names, base_stats)) # (x, y) -> {x: y} stats["bst"] = sum(base_stats) # sumo doesn't have a national dex :< if obj.species.id < 722: version = 26 else: version = 28 return { "table": "pokemon", "id": obj.species.id, "name": obj.name, "species": obj.species.genus, "type": [ptype.name for ptype in obj.types], "flavor": util.get(session, tables.PokemonSpeciesFlavorText, id=(obj.species.id,version,9)).flavor_text.replace('\n', ' '), "abilities": [ability.name for ability in obj.abilities], "hidden": obj.hidden_ability.name if obj.hidden_ability else None, "stats": stats, "link": 'https://veekun.com/dex/pokemon/' + link, "party": 'https://veekun.com/dex/media/pokemon/icons/' + sprite, "sprite": 'https://veekun.com/dex/media/pokemon/main-sprites/ultra-sun-ultra-moon/' + sprite, "color": colors[obj.types[0].name.lower()] }
def test_get_pokemon_id(id): result = util.get(session, tables.Pokemon, id=id) assert result.id == id assert result.__tablename__ == 'pokemon'
def test_get_pokemon_name_explicit_language(name): french = util.get(session, tables.Language, 'fr') poke = util.get(session, tables.PokemonSpecies, name=name, language=french) assert poke.name_map[french] == name, poke.name_map[french]
def test_types_french_order(): french = util.get(session, tables.Language, 'fr') types = session.query(tables.Type).filter(tables.Type.id < 10000) types = list(util.order_by_name(types, tables.Type, language=french)) assert types[0].name_map[french] == 'Acier', types[0].name_map[french] assert types[-1].name_map[french] == 'Vol', types[-1].name_map[french]
def test_get_pokemon_identifier(identifier): poke = util.get(session, tables.PokemonSpecies, identifier=identifier) assert poke.identifier == identifier
def test_get_pokemon_name(name): poke = util.get(session, tables.PokemonSpecies, name=name) assert poke.name == name
# Encoding: UTF-8 """Add XD tutors to the database This is an unmaintained one-shot script, only included in the repo for reference. """ from pokedex.db import connect, tables, util session = connect() emerald = util.get(session, tables.Version, 'emerald') fire_red = util.get(session, tables.Version, 'firered') emerald_version_group = emerald.version_group xd_version_group = util.get(session, tables.Version, 'xd').version_group colo_version_group = util.get(session, tables.Version, 'colosseum').version_group tutor = util.get(session, tables.PokemonMoveMethod, 'tutor') level_up = util.get(session, tables.PokemonMoveMethod, 'level-up') # According to every source I could find, the following can be taught to # exactly the same set of Pokémon which learn it from the FR/LG/E tutor: --ete for move_identifier in ''' body-slam double-edge dream-eater icy-wind mimic seismic-toss substitute
def mega_sharpedo(session): return util.get(session, tables.Pokemon, 'sharpedo-mega')
def import_print(session, card_info, do_commit=True): en = session.query(dex_tables.Language).get(session.default_language_id) card_name = card_info['name'] card = import_card( session, {k: v for k, v in card_info.items() if k in CARD_EXPORT_KEYS}) # Print bits illustrator_names = card_info.get('illustrators', ()) if 'illustrator' in card_info: illustrators.append(card_info.get('illustrator')) illustrators = [ get_illustrator(session, en, name) for name in illustrator_names ] if card_info.get('rarity'): rarity = util.get(session, tcg_tables.Rarity, card_info.get('rarity')) else: rarity = None dex_number = card_info.get('dex number', None) if dex_number: species = util.get(session, dex_tables.PokemonSpecies, id=dex_number) else: species = None # Make the print card_print = tcg_tables.Print() card_print.card = card card_print.rarity = rarity card_print.holographic = card_info.get('holographic') scan = tcg_tables.Scan() scan.print_ = card_print scan.filename = card_info.get('filename') scan.order = 0 session.add(scan) session.add(card_print) for i, illustrator in enumerate(illustrators): link = tcg_tables.PrintIllustrator() link.print_ = card_print link.illustrator = illustrator link.order = i session.add(link) if dex_number or any( x in card_info for x in ('height', 'weight', 'dex entry', 'species')): session.flush() flavor = tcg_tables.PokemonFlavor() if dex_number: species_name = card_info.get('pokemon') if species.name.lower() != species_name.lower(): raise ValueError("{!r} != {!r}".format(species.name, species_name)) flavor.species = species if 'height' in card_info: feet, inches = card_info.get('height').split("'") flavor.height = int(feet) * 12 + int(inches) if 'weight' in card_info: flavor.weight = card_info.get('weight') session.add(flavor) session.flush() if any(x in card_info for x in ('dex entry', 'species')): link = tcg_tables.PokemonFlavor.flavor_table() link.local_language = en link.tcg_pokemon_flavor_id = flavor.id if 'dex entry' in card_info: link.dex_entry = card_info.get('dex entry') if 'species' in card_info: link.genus = card_info.get('species') session.add(link) card_print.pokemon_flavor = flavor else: flavor = None card_info.pop('orphan', None) # XXX card_info.pop('has-variant', None) # XXX card_info.pop('dated', None) # XXX card_info.pop('in-set-variant-of', None) # XXX session.flush() # TODO: make sure we actually roundtrip! # assert_dicts_equal(card_info, export_print(card_print)) if do_commit: session.commit() return card_print
def nonzero_id(cls): with pytest.raises(NoResultFound): util.get(session, cls, id=0)
def test_types_french_order(session): french = util.get(session, tables.Language, 'fr') types = session.query(tables.Type).filter(tables.Type.id < 10000) types = list(util.order_by_name(types, tables.Type, language=french)) assert types[0].name_map[french] == 'Acier', types[0].name_map[french] assert types[-1].name_map[french] == 'Vol', types[-1].name_map[french]
def test_get_item_identifier(session): item = util.get(session, tables.Item, identifier='master-ball') assert item.name == 'Master Ball'
def test_get_pokemon_name(session, name): poke = util.get(session, tables.PokemonSpecies, name=name) assert poke.name == name
def test_get_english_by_identifier(session): language = util.get(session, tables.Language, 'en') assert language.name == 'English'
# Encoding: UTF-8 """Add XD tutors to the database This is an unmaintained one-shot script, only included in the repo for reference. """ from pokedex.db import connect, tables, util session = connect() emerald = util.get(session, tables.Version, 'emerald') fire_red = util.get(session, tables.Version, 'firered') emerald_version_group = emerald.version_group xd_version_group = util.get(session, tables.Version, 'xd').version_group colo_version_group = util.get(session, tables.Version, 'colosseum').version_group tutor = util.get(session, tables.PokemonMoveMethod, 'tutor') level_up = util.get(session, tables.PokemonMoveMethod, 'level-up') # According to every source I could find, the following can be taught to # exactly the same set of Pokémon which learn it from the FR/LG/E tutor: --ete for move_identifier in ''' body-slam double-edge dream-eater icy-wind mimic seismic-toss substitute swagger
def test_get_item_identifier(): item = util.get(session, tables.Item, identifier='master-ball') assert item.name == 'Master Ball'
def test_get_item_name(): item = util.get(session, tables.Item, name='Awakening') assert item.name == 'Awakening'
# Encoding: UTF-8 """Add XD tutors to the database This is an unmaintained one-shot script, only included in the repo for reference. """ from pokedex.db import connect, tables, util session = connect() emerald = util.get(session, tables.Version, "emerald") fire_red = util.get(session, tables.Version, "firered") emerald_version_group = emerald.version_group xd_version_group = util.get(session, tables.Version, "xd").version_group colo_version_group = util.get(session, tables.Version, "colosseum").version_group tutor = util.get(session, tables.PokemonMoveMethod, "tutor") level_up = util.get(session, tables.PokemonMoveMethod, "level-up") # According to every source I could find, the following can be taught to # exactly the same set of Pokémon which learn it from the FR/LG/E tutor: --ete for move_identifier in """ body-slam double-edge dream-eater icy-wind mimic seismic-toss substitute swagger
def test_get_english_by_identifier(): language = util.get(session, tables.Language, 'en') assert language.name == 'English'
def test_get_item_name(session): item = util.get(session, tables.Item, name='Awakening') assert item.name == 'Awakening'
def pikachu(session): return util.get(session, tables.Pokemon, 'pikachu')
def test_get_pokemon_identifier(session, identifier): poke = util.get(session, tables.PokemonSpecies, identifier=identifier) assert poke.identifier == identifier
def import_print(session, card_info, do_commit=True): en = session.query(dex_tables.Language).get(session.default_language_id) card_name = card_info['name'] card = import_card(session, {k: v for k, v in card_info.items() if k in CARD_EXPORT_KEYS}) # Print bits illustrator_names = card_info.get('illustrators', ()) if 'illustrator' in card_info: illustrators.append(card_info.get('illustrator')) illustrators = [get_illustrator(session, en, name) for name in illustrator_names] if card_info.get('rarity'): rarity = util.get(session, tcg_tables.Rarity, card_info.get('rarity')) else: rarity = None dex_number = card_info.get('dex number', None) if dex_number: species = util.get(session, dex_tables.PokemonSpecies, id=dex_number) else: species = None # Make the print card_print = tcg_tables.Print() card_print.card = card card_print.rarity = rarity card_print.holographic = card_info.get('holographic') scan = tcg_tables.Scan() scan.print_ = card_print scan.filename = card_info.get('filename') scan.order = 0 session.add(scan) session.add(card_print) for i, illustrator in enumerate(illustrators): link = tcg_tables.PrintIllustrator() link.print_ = card_print link.illustrator = illustrator link.order = i session.add(link) if dex_number or any(x in card_info for x in ( 'height', 'weight', 'dex entry', 'species')): session.flush() flavor = tcg_tables.PokemonFlavor() if dex_number: species_name = card_info.get('pokemon') if species.name.lower() != species_name.lower(): raise ValueError("{!r} != {!r}".format( species.name, species_name)) flavor.species = species if 'height' in card_info: feet, inches = card_info.get('height').split("'") flavor.height = int(feet) * 12 + int(inches) if 'weight' in card_info: flavor.weight = card_info.get('weight') session.add(flavor) session.flush() if any(x in card_info for x in ('dex entry', 'species')): link = tcg_tables.PokemonFlavor.flavor_table() link.local_language = en link.tcg_pokemon_flavor_id = flavor.id if 'dex entry' in card_info: link.dex_entry = card_info.get('dex entry') if 'species' in card_info: link.genus = card_info.get('species') session.add(link) card_print.pokemon_flavor = flavor else: flavor = None card_info.pop('orphan', None) # XXX card_info.pop('has-variant', None) # XXX card_info.pop('dated', None) # XXX card_info.pop('in-set-variant-of', None) # XXX session.flush() # TODO: make sure we actually roundtrip! # assert_dicts_equal(card_info, export_print(card_print)) if do_commit: session.commit() return card_print
def test_get_pokemon_name_explicit_language(session, name): french = util.get(session, tables.Language, 'fr') poke = util.get(session, tables.PokemonSpecies, name=name, language=french) assert poke.name_map[french] == name, poke.name_map[french]
def test_get_pokemon_id(session, id): result = util.get(session, tables.Pokemon, id=id) assert result.id == id assert result.__tablename__ == 'pokemon'
def from_pokemon_id(id_: int) -> Optional['PokemonEntry']: try: pokemon = util.get(session, tables.Pokemon, id=id_) return PokemonEntry(pokemon) except NoResultFound: return None
def import_card(session, card_info): def type_by_initial(initial): query = session.query(tcg_tables.TCGType) query = query.filter_by(initial=initial) return query.one() en = session.query(dex_tables.Language).get(session.default_language_id) card_name = card_info['name'] if 'stage' in card_info: stage = util.get(session, tcg_tables.Stage, name=card_info.get('stage')) else: stage = None if card_info.get('class'): card_class = util.get(session, tcg_tables.Class, card_class_idents[card_info.get('class')]) else: card_class = None hp = card_info.get('hp', None) retreat_cost = card_info.get('retreat', None) card_types = tuple( util.get(session, tcg_tables.TCGType, name=t) for t in card_info.get('types', ())) damage_mod_info = card_info.get('damage modifiers', []) card_family = get_family(session, en, card_name) # Find/make corresponding card query = session.query(tcg_tables.Card) query = query.filter(tcg_tables.Card.stage == stage) query = query.filter(tcg_tables.Card.hp == hp) query = query.filter(tcg_tables.Card.class_ == card_class) query = query.filter(tcg_tables.Card.retreat_cost == retreat_cost) query = query.filter(tcg_tables.Card.family == card_family) query = query.options(joinedload('family')) query = query.options(joinedload_all('card_types.type.names')) query = query.options(subqueryload_all('card_mechanics.mechanic.names')) query = query.options(subqueryload_all('card_subclasses.subclass.names')) card_query = query for card in card_query.all(): if card.types != card_types: continue mnames = [m.mechanic.name for m in card.card_mechanics] if mnames != [m.get('name') for m in card_info.get('mechanics', [])]: continue if card_info == export_card(card): return card # No card found, make a new one card = tcg_tables.Card() card.stage = stage card.class_ = card_class card.hp = hp card.retreat_cost = retreat_cost card.legal = card_info.get('legal', False) card.family = card_family session.add(card) for mechanic_index, mechanic_info in enumerate( card_info.get('mechanics', ())): # Mechanic bits mechanic_name = mechanic_info.get('name', None) effect = mechanic_info.get('text', None) cost_string = mechanic_info.get('cost', '') mechanic_class = util.get( session, tcg_tables.MechanicClass, mechanic_info.get('type')) damage = mechanic_info.get('damage', None) # Find/make mechanic query = session.query(tcg_tables.Mechanic) if mechanic_name: query = util.filter_name(query, tcg_tables.Mechanic, mechanic_name, en) if effect: query = query.filter(tcg_tables.Mechanic.effect == effect) query = query.filter(tcg_tables.Mechanic.class_ == mechanic_class) for mechanic in query.all(): if export_mechanic(mechanic) == mechanic_info: break else: mechanic = None if not mechanic: mechanic = tcg_tables.Mechanic() mechanic.name_map[en] = mechanic_name mechanic.effect_map[en] = effect mechanic.class_ = mechanic_class if cost_string == '#': cost_string = '' cost_list = list(cost_string) cost_index = 0 while cost_list: cost = tcg_tables.MechanicCost() initial = cost_list[0] cost.type = type_by_initial(initial) cost.amount = 0 while cost_list and cost_list[0] == initial: cost.amount += 1 del cost_list[0] cost.mechanic = mechanic cost.order = cost_index cost_index += 1 session.add(cost) if damage: if damage.endswith(('+', '-', '?', '×')): mechanic.damage_modifier = damage[-1] damage = damage[:-1] if damage: mechanic.damage_base = int(damage) session.add(mechanic) link = tcg_tables.CardMechanic() link.card = card link.mechanic = mechanic link.order = mechanic_index session.add(link) for type_index, card_type in enumerate(card_types): link = tcg_tables.CardType() link.card = card link.type = card_type link.order = type_index session.add(link) for dm_index, dm_info in enumerate(damage_mod_info): dm_type = util.get(session, tcg_tables.TCGType, name=dm_info.get('type')) modifier = tcg_tables.DamageModifier() modifier.card = card modifier.type = dm_type modifier.amount = dm_info.get('amount') modifier.order = dm_index modifier.operation = dm_info.get('operation') session.add(modifier) session.flush() for subclass_index, subclass_name in enumerate( card_info.get('subclasses', ())): try: subclass = util.get(session, tcg_tables.Subclass, name=subclass_name) except NoResultFound: subclass = tcg_tables.Subclass() subclass.identifier = identifier_from_name( subclass_name) subclass.name_map[en] = subclass_name session.add(subclass) link = tcg_tables.CardSubclass() link.card = card link.subclass = subclass link.order = subclass_index session.add(link) for evolves_from in card_info.get('evolves from', []): family = get_family(session, en, evolves_from) link = tcg_tables.Evolution() link.card = card link.family = family link.order = 0 link.family_to_card = True session.add(link) for evolves_into in card_info.get('evolves into', []): family = get_family(session, en, evolves_into) link = tcg_tables.Evolution() link.card = card link.family = family link.order = 0 link.family_to_card = False session.add(link) # TODO: make sure we actually roundtrip! #assert_dicts_equal(card_info, export_card(card)) return card
def import_card(session, card_info): def type_by_initial(initial): query = session.query(tcg_tables.TCGType) query = query.filter_by(initial=initial) return query.one() en = session.query(dex_tables.Language).get(session.default_language_id) card_name = card_info['name'] if 'stage' in card_info: stage = util.get(session, tcg_tables.Stage, name=card_info.get('stage')) else: stage = None if card_info.get('class'): card_class = util.get(session, tcg_tables.Class, card_class_idents[card_info.get('class')]) else: card_class = None hp = card_info.get('hp', None) retreat_cost = card_info.get('retreat', None) card_types = tuple( util.get(session, tcg_tables.TCGType, name=t) for t in card_info.get('types', ())) damage_mod_info = card_info.get('damage modifiers', []) card_family = get_family(session, en, card_name) # Find/make corresponding card query = session.query(tcg_tables.Card) query = query.filter(tcg_tables.Card.stage == stage) query = query.filter(tcg_tables.Card.hp == hp) query = query.filter(tcg_tables.Card.class_ == card_class) query = query.filter(tcg_tables.Card.retreat_cost == retreat_cost) query = query.filter(tcg_tables.Card.family == card_family) query = query.options(joinedload('family')) query = query.options(joinedload_all('card_types.type.names')) query = query.options(subqueryload_all('card_mechanics.mechanic.names')) query = query.options(subqueryload_all('card_subclasses.subclass.names')) card_query = query for card in card_query.all(): if card.types != card_types: continue mnames = [m.mechanic.name for m in card.card_mechanics] if mnames != [m.get('name') for m in card_info.get('mechanics', [])]: continue if card_info == export_card(card): return card # No card found, make a new one card = tcg_tables.Card() card.stage = stage card.class_ = card_class card.hp = hp card.retreat_cost = retreat_cost card.legal = card_info.get('legal', False) card.family = card_family session.add(card) for mechanic_index, mechanic_info in enumerate( card_info.get('mechanics', ())): # Mechanic bits mechanic_name = mechanic_info.get('name', None) effect = mechanic_info.get('text', None) cost_string = mechanic_info.get('cost', '') mechanic_class = util.get(session, tcg_tables.MechanicClass, mechanic_info.get('type')) damage = mechanic_info.get('damage', None) # Find/make mechanic query = session.query(tcg_tables.Mechanic) if mechanic_name: query = util.filter_name(query, tcg_tables.Mechanic, mechanic_name, en) if effect: query = query.filter(tcg_tables.Mechanic.effect == effect) query = query.filter(tcg_tables.Mechanic.class_ == mechanic_class) for mechanic in query.all(): if export_mechanic(mechanic) == mechanic_info: break else: mechanic = None if not mechanic: mechanic = tcg_tables.Mechanic() mechanic.name_map[en] = mechanic_name mechanic.effect_map[en] = effect mechanic.class_ = mechanic_class if cost_string == '#': cost_string = '' cost_list = list(cost_string) cost_index = 0 while cost_list: cost = tcg_tables.MechanicCost() initial = cost_list[0] cost.type = type_by_initial(initial) cost.amount = 0 while cost_list and cost_list[0] == initial: cost.amount += 1 del cost_list[0] cost.mechanic = mechanic cost.order = cost_index cost_index += 1 session.add(cost) if damage: if damage.endswith(('+', '-', '?', '×')): mechanic.damage_modifier = damage[-1] damage = damage[:-1] if damage: mechanic.damage_base = int(damage) session.add(mechanic) link = tcg_tables.CardMechanic() link.card = card link.mechanic = mechanic link.order = mechanic_index session.add(link) for type_index, card_type in enumerate(card_types): link = tcg_tables.CardType() link.card = card link.type = card_type link.order = type_index session.add(link) for dm_index, dm_info in enumerate(damage_mod_info): dm_type = util.get(session, tcg_tables.TCGType, name=dm_info.get('type')) modifier = tcg_tables.DamageModifier() modifier.card = card modifier.type = dm_type modifier.amount = dm_info.get('amount') modifier.order = dm_index modifier.operation = dm_info.get('operation') session.add(modifier) session.flush() for subclass_index, subclass_name in enumerate( card_info.get('subclasses', ())): try: subclass = util.get(session, tcg_tables.Subclass, name=subclass_name) except NoResultFound: subclass = tcg_tables.Subclass() subclass.identifier = identifier_from_name(subclass_name) subclass.name_map[en] = subclass_name session.add(subclass) link = tcg_tables.CardSubclass() link.card = card link.subclass = subclass link.order = subclass_index session.add(link) for evolves_from in card_info.get('evolves from', []): family = get_family(session, en, evolves_from) link = tcg_tables.Evolution() link.card = card link.family = family link.order = 0 link.family_to_card = True session.add(link) for evolves_into in card_info.get('evolves into', []): family = get_family(session, en, evolves_into) link = tcg_tables.Evolution() link.card = card link.family = family link.order = 0 link.family_to_card = False session.add(link) # TODO: make sure we actually roundtrip! #assert_dicts_equal(card_info, export_card(card)) return card