You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

139 lines
5.0 KiB

import sqlite3
from typing import List, Optional
from dataclasses import dataclass
from fuzzywuzzy import fuzz
import re
from cache_manager import CacheManager
from DetermineOriginGame import get_evolution_data_from_bulbapedia
@dataclass
class EvolutionInfo:
from_pfic: str
to_pfic: str
method: str
def create_evolution_table():
conn = sqlite3.connect('pokemon_forms.db')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS evolution_chains (
from_pfic TEXT,
to_pfic TEXT,
method TEXT,
PRIMARY KEY (from_pfic, to_pfic),
FOREIGN KEY (from_pfic) REFERENCES pokemon_forms (PFIC),
FOREIGN KEY (to_pfic) REFERENCES pokemon_forms (PFIC)
)
''')
conn.commit()
return conn
def insert_evolution_info(conn, evolution_info: EvolutionInfo):
cursor = conn.cursor()
cursor.execute('''
INSERT OR REPLACE INTO evolution_chains
(from_pfic, to_pfic, method)
VALUES (?, ?, ?)
''', (evolution_info.from_pfic, evolution_info.to_pfic, evolution_info.method))
conn.commit()
def strip_pokemon_name(pokemon_name: str, form_name: str) -> str:
"""Remove the Pokémon's name from the form name if present."""
if form_name:
form_name = form_name.replace("Form", "").strip()
form_name = re.sub(f'{re.escape(pokemon_name)}\\s*', '', form_name, flags=re.IGNORECASE).strip()
form_name = form_name.replace(" ", " ")
return form_name
return form_name
def fuzzy_match_form(form1: str, form2: str, threshold: int = 80) -> bool:
"""Perform fuzzy matching between two form names."""
if form1 is None or form2 is None:
return form1 == form2
return fuzz.ratio(form1.lower(), form2.lower()) >= threshold
def get_pokemon_form_by_name(conn, name: str, form: Optional[str] = None, threshold: int = 80, gender: Optional[str] = None) -> Optional[str]:
cursor = conn.cursor()
cursor.execute('SELECT PFIC, name, form_name FROM pokemon_forms WHERE name = ?', (name,))
results = cursor.fetchall()
if not results:
return None
if form is None and gender is None:
if len(results) > 1:
if results[0][2] == None:
return results[0][0]
else:
return get_pokemon_form_by_name(conn, name, "Male", threshold=100, gender=gender)
else:
return results[0][0] # Return the PFIC of the first result if no form is specified
if gender:
gendered_form = get_pokemon_form_by_name(conn, name, gender, threshold=100)
if gendered_form:
return gendered_form
stripped_form = strip_pokemon_name(name, form)
for pfic, pokemon_name, db_form in results:
stripped_db_form = strip_pokemon_name(pokemon_name, db_form)
if fuzzy_match_form(stripped_form, stripped_db_form, threshold):
return pfic
# Some times we get a form for a pokemon that doesn't really have one.
if len(results) > 1 and form != None:
return results[0][0]
return None
def process_evolution_chain(conn, evolution_chain, cache, gender: Optional[str] = None):
for stage in evolution_chain:
from_pfic = get_pokemon_form_by_name(conn, stage.pokemon, stage.form, gender=gender)
if not from_pfic:
print(f"Warning: Could not find PFIC for {stage.pokemon} {stage.form}")
continue
if stage.next_stage:
to_pfic = get_pokemon_form_by_name(conn, stage.next_stage.pokemon, stage.next_stage.form, gender=gender)
if to_pfic:
evolution_info = EvolutionInfo(from_pfic, to_pfic, stage.next_stage.method)
insert_evolution_info(conn, evolution_info)
for branch in stage.branches:
to_pfic = get_pokemon_form_by_name(conn, branch.pokemon, branch.form, gender=gender)
if to_pfic:
evolution_info = EvolutionInfo(from_pfic, to_pfic, branch.method)
insert_evolution_info(conn, evolution_info)
def update_evolution_chains():
cache = CacheManager()
conn = create_evolution_table()
cursor = conn.cursor()
cursor.execute('SELECT DISTINCT name, form_name FROM pokemon_forms')
pokemon_forms = cursor.fetchall()
for name, form in pokemon_forms:
print(f"Processing {name} {form if form else ''}")
if form and name in form:
form = form.replace(name, "").strip()
gender = None
if form and "male" in form.lower():
gender = form
form = None
evolution_chain = get_evolution_data_from_bulbapedia(name, form, cache, gender)
if evolution_chain:
if name == "Tauros": # Bulbapedia has a weird formatting for Tauros.
for stage in evolution_chain:
if stage.form:
stage.form = stage.form.replace("Paldean Form(", "").replace(")", "").strip()
process_evolution_chain(conn, evolution_chain, cache, gender)
conn.close()
if __name__ == "__main__":
update_evolution_chains()