|
|
|
@ -11,7 +11,7 @@ from utility.functions import get_form_name, get_display_name, parse_pfic |
|
|
|
from utility.data import non_evolution_forms |
|
|
|
|
|
|
|
class GatherEvolutionsWorkerSignals(QObject): |
|
|
|
finished = pyqtSignal(list) |
|
|
|
finished = pyqtSignal(dict) |
|
|
|
|
|
|
|
class GatherEvolutions(QRunnable): |
|
|
|
def __init__(self): |
|
|
|
@ -19,6 +19,8 @@ class GatherEvolutions(QRunnable): |
|
|
|
self.signals = GatherEvolutionsWorkerSignals() |
|
|
|
self.base_url = "https://bulbapedia.bulbagarden.net/wiki/" |
|
|
|
|
|
|
|
self.evolution_methods = set() |
|
|
|
|
|
|
|
def run(self): |
|
|
|
try: |
|
|
|
gathered_data = self.gather_evolution_data() |
|
|
|
@ -28,7 +30,6 @@ class GatherEvolutions(QRunnable): |
|
|
|
|
|
|
|
def gather_evolution_data(self, force_refresh = True): |
|
|
|
all_pokemon_forms = db.get_list_of_pokemon_forms() |
|
|
|
#evolutions = [] |
|
|
|
evolutions = {} |
|
|
|
|
|
|
|
for pokemon_form in all_pokemon_forms: |
|
|
|
@ -90,55 +91,15 @@ class GatherEvolutions(QRunnable): |
|
|
|
evolution_tree = None |
|
|
|
if pokemon_name == "Eevee": |
|
|
|
evolution_tree = self.parse_eevee_evolution_chain(evolution_table, pokemon_form) |
|
|
|
#evolutions.append(evolution_chain) |
|
|
|
else: |
|
|
|
evolution_tree = self.parse_evolution_chain(evolution_table, pokemon_form) |
|
|
|
#evolutions.append(evolution_chain) |
|
|
|
|
|
|
|
if evolution_tree: |
|
|
|
self.traverse_and_store(evolution_tree, evolutions, gender) |
|
|
|
|
|
|
|
chain = [] |
|
|
|
for pokemon in evolution_chain: |
|
|
|
from_pfic = self.get_pokemon_form_by_name(pokemon["pokemon"], pokemon["form"], gender=gender) |
|
|
|
if not from_pfic: |
|
|
|
#logger.warning(f"Could not find PFIC for {stage.pokemon} {stage.form}") |
|
|
|
continue |
|
|
|
|
|
|
|
stage = pokemon["next_stage"] |
|
|
|
if stage: |
|
|
|
to_pfic = self.get_pokemon_form_by_name(stage["pokemon"], stage["form"], gender=gender) |
|
|
|
if to_pfic: |
|
|
|
evolution_info = { |
|
|
|
"from_pfic": from_pfic, |
|
|
|
"to_pfic": to_pfic, |
|
|
|
"method": stage["method"] |
|
|
|
} |
|
|
|
evolutions[pokemon_form["pfic"]] = evolution_info |
|
|
|
chain.append(evolution_info) |
|
|
|
|
|
|
|
#insert_evolution_info(evolution_info) |
|
|
|
|
|
|
|
#if "breed" in stage["next_stage"]["method"].lower(): |
|
|
|
# update_pokemon_baby_status(from_pfic, True) |
|
|
|
|
|
|
|
for branch in pokemon["branches"]: |
|
|
|
to_pfic = self.get_pokemon_form_by_name(branch["pokemon"], branch["form"], gender=gender) |
|
|
|
if to_pfic: |
|
|
|
evolution_info = { |
|
|
|
"from_pfic": from_pfic, |
|
|
|
"to_pfic": to_pfic, |
|
|
|
"method": branch["method"] |
|
|
|
} |
|
|
|
evolutions[pokemon_form["pfic"]] = evolution_info |
|
|
|
chain.append(evolution_info) |
|
|
|
#EvolutionInfo(from_pfic, to_pfic, branch.method) |
|
|
|
#insert_evolution_info(evolution_info) |
|
|
|
|
|
|
|
#if "breed" in branch.method.lower(): |
|
|
|
# update_pokemon_baby_status(from_pfic, True) |
|
|
|
cache.set(cache_record_name, chain) |
|
|
|
#cache.set(cache_record_name, chain) |
|
|
|
|
|
|
|
print(self.evolution_methods) |
|
|
|
return evolutions |
|
|
|
|
|
|
|
def traverse_and_store(self, node, evolutions, gender): |
|
|
|
@ -159,7 +120,7 @@ class GatherEvolutions(QRunnable): |
|
|
|
evolutions[composite_key] = (evolution_info) |
|
|
|
self.traverse_and_store(next_stage, evolutions, gender) |
|
|
|
|
|
|
|
def parse_evolution_chain(self, table, pokemon_form, force_refresh = False): |
|
|
|
def parse_evolution_chain(self, table, pokemon_form, force_refresh = True): |
|
|
|
cache_record_name = f"evo_{pokemon_form['pfic']}" |
|
|
|
if force_refresh: |
|
|
|
cache.purge(cache_record_name) |
|
|
|
@ -178,59 +139,85 @@ class GatherEvolutions(QRunnable): |
|
|
|
main_row = rows[0] |
|
|
|
branch_rows = rows[1:] |
|
|
|
|
|
|
|
def create_stage(td): |
|
|
|
def create_stage(td, current_stage_number): |
|
|
|
pokemon_name = self.extract_pokemon_name(td) |
|
|
|
evolution_form = self.extract_evolution_form(td, pokemon_name) |
|
|
|
return { |
|
|
|
"pokemon": pokemon_name, |
|
|
|
"form": evolution_form, |
|
|
|
"requirement": None, |
|
|
|
"method": None, |
|
|
|
"evolves_to": [] |
|
|
|
"evolves_to": [], |
|
|
|
"stage": current_stage_number |
|
|
|
} |
|
|
|
|
|
|
|
# Parse main evolution chain |
|
|
|
pending_method = None |
|
|
|
pending_method_form = None |
|
|
|
root = None |
|
|
|
current_stage = None |
|
|
|
stage_number = 0 |
|
|
|
|
|
|
|
for td in main_row.find_all('td', recursive=False): |
|
|
|
if td.find('table'): |
|
|
|
new_stage = create_stage(td) |
|
|
|
new_stage = create_stage(td, stage_number) |
|
|
|
new_stage["method"] = pending_method |
|
|
|
new_stage["requirement"] = pending_method_form |
|
|
|
pending_method = None |
|
|
|
if root is None: |
|
|
|
root = new_stage # Assign the root node |
|
|
|
if current_stage: |
|
|
|
current_stage["evolves_to"].append(new_stage) |
|
|
|
current_stage = new_stage |
|
|
|
stage_number += 1 |
|
|
|
else: |
|
|
|
pending_method = self.extract_evolution_method(td) |
|
|
|
pending_method, pending_method_form = self.extract_evolution_method(td) |
|
|
|
|
|
|
|
# reduce by one to account for an accidental increase by the last one in the chain. |
|
|
|
stage_number -= 1 |
|
|
|
|
|
|
|
# Parse branching evolutions |
|
|
|
for row in branch_rows: |
|
|
|
branch_method = None |
|
|
|
pending_method_form = None |
|
|
|
branch_stage = None |
|
|
|
branch_stage_number = stage_number |
|
|
|
|
|
|
|
for td in row.find_all('td', recursive=False): |
|
|
|
if td.find('table'): |
|
|
|
new_stage = create_stage(td) |
|
|
|
new_stage = create_stage(td, branch_stage_number) |
|
|
|
new_stage["method"] = branch_method |
|
|
|
new_stage["requirement"] = pending_method_form |
|
|
|
branch_method = None |
|
|
|
|
|
|
|
if branch_stage: |
|
|
|
branch_stage["evolves_to"].append(new_stage) |
|
|
|
branch_stage = new_stage |
|
|
|
|
|
|
|
# Find which main chain Pokémon this branches from |
|
|
|
# Find which main chain Pokémon this branch evolves from |
|
|
|
attached = False |
|
|
|
for main_stage in self.find_stages(root): |
|
|
|
if td.get('rowspan') and main_stage["pokemon"] == new_stage["pokemon"]: |
|
|
|
if self.should_attach_branch(main_stage, branch_stage): |
|
|
|
main_stage["evolves_to"].append(branch_stage) |
|
|
|
attached = True |
|
|
|
break |
|
|
|
|
|
|
|
if not attached: |
|
|
|
print(f"Warning: Could not find a suitable attachment point for branch {branch_stage['pokemon']}") |
|
|
|
else: |
|
|
|
branch_method = self.extract_evolution_method(td) |
|
|
|
branch_method, pending_method_form = self.extract_evolution_method(td) |
|
|
|
|
|
|
|
cache.set(cache_record_name, root) |
|
|
|
return root |
|
|
|
|
|
|
|
def should_attach_branch(self, main_stage, branch_stage): |
|
|
|
# Ensure the main_stage is a valid node to attach a branch |
|
|
|
if main_stage["stage"] == branch_stage["stage"] - 1: |
|
|
|
return True |
|
|
|
# You can add more logic to determine if branch_stage should connect to main_stage |
|
|
|
# For instance, check if they are forms of the same evolution or based on other criteria |
|
|
|
return False |
|
|
|
|
|
|
|
def find_stages(self, node): |
|
|
|
"""Helper function to find all stages in the evolution chain recursively.""" |
|
|
|
stages = [node] |
|
|
|
@ -269,7 +256,14 @@ class GatherEvolutions(QRunnable): |
|
|
|
|
|
|
|
def extract_evolution_method(self, td: Tag) -> str: |
|
|
|
# Extract evolution method from the TD |
|
|
|
return td.get_text(strip=True) |
|
|
|
text = td.get_text() |
|
|
|
form = None |
|
|
|
if text and "(male)" in text.lower(): |
|
|
|
form = "male" |
|
|
|
elif text and "(female)" in text.lower(): |
|
|
|
form = "female" |
|
|
|
|
|
|
|
return td.get_text(strip=True), form |
|
|
|
|
|
|
|
def parse_eevee_evolution_chain(self, table, pokemon_form): |
|
|
|
tbody = table.find('tbody', recursive=False) |
|
|
|
@ -376,8 +370,8 @@ class GatherEvolutions(QRunnable): |
|
|
|
return entry["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]["pfic"] |
|
|
|
#if len(results) > 1 and form != None and gender and threshold != 100: |
|
|
|
# return results[0]["pfic"] |
|
|
|
|
|
|
|
return None |
|
|
|
|
|
|
|
|