mirror of
https://github.com/veekun/pokedex.git
synced 2024-08-20 18:16:34 +00:00
167 lines
5.7 KiB
Python
167 lines
5.7 KiB
Python
|
# Encoding: UTF-8
|
||
|
"""Load events and special encounters from a CSV file
|
||
|
|
||
|
This is an unmaintained one-shot script, only included in the repo for reference.
|
||
|
|
||
|
Loads the data from an ad-hoc spreadsheet format, because for getting this stuff
|
||
|
together, flat is definitely better than nested.
|
||
|
|
||
|
"""
|
||
|
|
||
|
from __future__ import unicode_literals
|
||
|
|
||
|
import sys
|
||
|
import csv
|
||
|
|
||
|
from sqlalchemy.sql.expression import func
|
||
|
from sqlalchemy.orm import subqueryload
|
||
|
import sqlalchemy.orm.exc
|
||
|
|
||
|
from pokedex.db import connect, tables, util, load
|
||
|
|
||
|
session = connect()
|
||
|
|
||
|
reader = ([c.decode('utf-8') for c in l] for l in csv.reader(open(sys.argv[1])))
|
||
|
reader.next() # discard line 1
|
||
|
column_names = reader.next()
|
||
|
print ','.join(column_names)
|
||
|
|
||
|
english = util.get(session, tables.Language, 'en')
|
||
|
|
||
|
def create_with_autoid(table):
|
||
|
autoid = (session.query(func.max(table.id)).one()[0] or 0) + 1
|
||
|
obj = table()
|
||
|
obj.id = autoid
|
||
|
return obj
|
||
|
|
||
|
# We need location_areas for places that don't have them yet
|
||
|
for location in session.query(tables.Location).options(subqueryload('areas')):
|
||
|
if not location.areas:
|
||
|
print 'Creating default area for', location.identifier
|
||
|
area = create_with_autoid(tables.LocationArea)
|
||
|
area.location = location
|
||
|
session.add(area)
|
||
|
|
||
|
def trainer(name, number):
|
||
|
if name is number is None:
|
||
|
return None
|
||
|
query = session.query(tables.Trainer).join(tables.Trainer.names)
|
||
|
query = query.filter(tables.Trainer.names_table.name == name)
|
||
|
query = query.filter(tables.Trainer.number == number)
|
||
|
try:
|
||
|
return query.one()
|
||
|
except sqlalchemy.orm.exc.NoResultFound:
|
||
|
trainer = create_with_autoid(tables.Trainer)
|
||
|
trainer_name = tables.Trainer.names_table()
|
||
|
trainer_name.local_language = english
|
||
|
trainer_name.foreign_id = trainer.id
|
||
|
trainer_name.name = name
|
||
|
trainer.number = number
|
||
|
session.add(trainer)
|
||
|
session.add(trainer_name)
|
||
|
return trainer
|
||
|
|
||
|
version_codes = (
|
||
|
# 2-letter codes first!
|
||
|
('Xd', 'xd'),
|
||
|
('Co', 'colosseum'),
|
||
|
('Pt', 'platinum'),
|
||
|
('Hg', 'heartgold'),
|
||
|
('Ss', 'soulsilver'),
|
||
|
|
||
|
('R', 'red'),
|
||
|
('B', 'blue'),
|
||
|
('Y', 'yellow'),
|
||
|
|
||
|
('G', 'gold'),
|
||
|
('S', 'silver'),
|
||
|
('C', 'crystal'),
|
||
|
|
||
|
('R', 'ruby'),
|
||
|
('S', 'sapphire'),
|
||
|
('E', 'emerald'),
|
||
|
('F', 'firered'),
|
||
|
('L', 'leafgreen'),
|
||
|
|
||
|
('D', 'diamond'),
|
||
|
('P', 'pearl'),
|
||
|
|
||
|
('B', 'black'),
|
||
|
('W', 'white'),
|
||
|
)
|
||
|
|
||
|
for line in reader:
|
||
|
print ','.join(line)
|
||
|
line_dict = dict(zip(column_names, line + [''] * 100))
|
||
|
all_places = line_dict.pop('Place').split(',')
|
||
|
for p_form_ident in line_dict.pop('Species/Form').split(','):
|
||
|
p_form_ident = p_form_ident.strip()
|
||
|
for place_ident in all_places:
|
||
|
place_ident = place_ident.strip()
|
||
|
|
||
|
dct = dict(line_dict)
|
||
|
|
||
|
encounter_type = util.get(session, tables.SpecialEncounterType, dct.pop('Method'))
|
||
|
species_ident, sp, form_ident = p_form_ident.partition(' ')
|
||
|
species = util.get(session, tables.PokemonSpecies, species_ident)
|
||
|
for pokemon_form in species.forms:
|
||
|
if pokemon_form.form_identifier == (form_ident or None):
|
||
|
break
|
||
|
else:
|
||
|
raise ValueError('No such pkmn form: %s' % p_form_ident)
|
||
|
if place_ident:
|
||
|
location_ident, sp, area_ident = place_ident.partition(' ')
|
||
|
location = util.get(session, tables.Location, location_ident)
|
||
|
for location_area in location.areas:
|
||
|
if location_area.identifier == (area_ident or None):
|
||
|
break
|
||
|
else:
|
||
|
raise ValueError('No such area: %s' % place_ident)
|
||
|
else:
|
||
|
location_area = None
|
||
|
se_pokemon = create_with_autoid(tables.EventPokemon)
|
||
|
se_pokemon.pokemon_form = pokemon_form
|
||
|
se_pokemon.is_egg = bool(dct.pop('Egg'))
|
||
|
se_pokemon.cost = dct.pop('Cost') or None
|
||
|
session.add(se_pokemon)
|
||
|
encounter = create_with_autoid(tables.SpecialEncounter)
|
||
|
encounter.event_pokemon = se_pokemon
|
||
|
encounter.type = encounter_type
|
||
|
encounter.location_area = location_area
|
||
|
se_pokemon.level = dct.pop('Lv.') or None
|
||
|
se_pokemon.nickname = dct.pop('Name') or None
|
||
|
session.add(encounter)
|
||
|
if encounter_type == 'starter':
|
||
|
print
|
||
|
dct.pop('Notes')
|
||
|
versions = dct.pop('Version')
|
||
|
trade_for = dct.pop('Trade for')
|
||
|
if trade_for:
|
||
|
encounter.trade_species = util.get(session,
|
||
|
tables.PokemonSpecies, trade_for)
|
||
|
se_pokemon.original_trainer = trainer(
|
||
|
dct.pop('OT Name') or None, dct.pop('OT №') or None)
|
||
|
for code, version_ident in version_codes:
|
||
|
part1, current_code, part2 = versions.partition(code)
|
||
|
versions = part1 + part2
|
||
|
if current_code:
|
||
|
entry = tables.SpecialEncounterVersion()
|
||
|
entry.encounter = encounter
|
||
|
entry.version = util.get(session, tables.Version, version_ident)
|
||
|
session.add(entry)
|
||
|
assert not versions, 'Leftover versions: %s' % versions
|
||
|
assert not any(dct.values()), 'stuff left over: %s' % ', '.join(
|
||
|
'%s=%s' % (k, v) for k, v in dct.items() if v)
|
||
|
|
||
|
print 'Dumping!'
|
||
|
load.dump(session, verbose=True, tables=[
|
||
|
'special_encounters',
|
||
|
'event_pokemon',
|
||
|
'special_encounter_versions',
|
||
|
'location_areas',
|
||
|
'trainers',
|
||
|
'trainer_names',
|
||
|
])
|
||
|
|
||
|
session.rollback()
|