diff --git a/database/db_controller.py b/database/db_controller.py index 910175d..b405f15 100644 --- a/database/db_controller.py +++ b/database/db_controller.py @@ -195,6 +195,10 @@ class DBController: self.update_pokemon_field(pfic, "storable_in_home", status) pass + def update_baby_status(self, pfic, status): + self.update_pokemon_field(pfic, "is_baby_form", status) + pass + def update_mark(self, pfic, data): self.update_pokemon_field(pfic, "mark", data) pass @@ -600,7 +604,7 @@ class DBController: pre_processed_data = [dict(row) for row in results] for row in pre_processed_data: data = {} - data["PFIC"] = row["PFIC"] + data["pfic"] = row["PFIC"] if row["data"] and row["data"] != "": data.update(json.loads(row["data"])) diff --git a/ui/main_window_controller.py b/ui/main_window_controller.py index ec54237..afd23fa 100644 --- a/ui/main_window_controller.py +++ b/ui/main_window_controller.py @@ -4,6 +4,7 @@ from PyQt6.QtGui import QAction import os from ui.workers.calculate_origin_mark_worker import CalculateOriginMarkWorker +from ui.workers.gather_baby_form_status import GatherBabyStatusWorker from ui.workers.gather_encounter_locations import GatherEncountersWorker from ui.workers.gather_home_storage_status_worker import GatherHomeStorageStatus from ui.workers.gather_pokemon_forms_worker import GatherPokemonFormsWorker @@ -134,14 +135,15 @@ class MainWindowController: print("Works Done!") db.update_evolution_graph(data) - def adjust_gender_relevancy(self): - list = db.get_gender_specific_evolutions() - second_list = db.get_gender_relevant_pokemon() - print(list) - print(second_list) - db.propagate_gender_relevance(list) - db.propagate_gender_relevance(second_list) - pass + def gather_baby_status(self): + worker = GatherBabyStatusWorker() + worker.signals.finished.connect(self.on_baby_status_gathered) + self.thread_pool.start(worker) + + def on_baby_status_gathered(self, data): + print("Works Done!") + for pfic in data: + db.update_baby_status(pfic, True) def reinitialize_database(self): pass diff --git a/ui/main_window_view.py b/ui/main_window_view.py index 3d430c8..37d196b 100644 --- a/ui/main_window_view.py +++ b/ui/main_window_view.py @@ -154,8 +154,8 @@ class PokemonUI(QWidget): gather_evolutions_btn.clicked.connect(self.controller.gather_evolution_info) db_tab_layout.addWidget(gather_evolutions_btn) - gather_evolutions_btn = QPushButton("Adjust Gender Relevant Information") - gather_evolutions_btn.clicked.connect(self.controller.adjust_gender_relevancy) + gather_evolutions_btn = QPushButton("Gather Baby Status") + gather_evolutions_btn.clicked.connect(self.controller.gather_baby_status) db_tab_layout.addWidget(gather_evolutions_btn) gather_encounters_btn = QPushButton("Gather Encounter Information") diff --git a/ui/workers/gather_baby_form_status.py b/ui/workers/gather_baby_form_status.py new file mode 100644 index 0000000..4600256 --- /dev/null +++ b/ui/workers/gather_baby_form_status.py @@ -0,0 +1,39 @@ +from PyQt6.QtCore import QObject, pyqtSignal, QRunnable +import json + +from cache import cache +from db import db + +from ui.workers.gather_evolutions_worker import GatherEvolutions +from utility.data import exclusive_choice_pokemon +from utility.functions import get_display_name, get_form_name, get_shiftable_forms, parse_pfic + +class GatherBabyStatusWorkerSignals(QObject): + finished = pyqtSignal(list) + +class GatherBabyStatusWorker(GatherEvolutions): + def __init__(self): + super().__init__() + self.signals = GatherBabyStatusWorkerSignals() + + def run(self): + try: + gathered_data = self.gather_baby_status(False) + self.signals.finished.emit(gathered_data) + except Exception as e: + print(f"Error gathering Pokémon home storage status: {e}") + + def gather_baby_status(self, force_refresh = False): + all_pokemon_forms = db.get_pokemon_home_list() + babys = [] + + for pokemon_form in all_pokemon_forms: + evolution_tree = self.gather_evolution_tree(pokemon_form, force_refresh) + if not evolution_tree: + continue + if evolution_tree["pokemon"] != pokemon_form["name"]: + continue + if evolution_tree["is_baby"]: + babys.append(pokemon_form["pfic"]) + + return babys \ No newline at end of file diff --git a/ui/workers/gather_evolutions_worker.py b/ui/workers/gather_evolutions_worker.py index 91550ab..76dd369 100644 --- a/ui/workers/gather_evolutions_worker.py +++ b/ui/workers/gather_evolutions_worker.py @@ -34,109 +34,119 @@ class GatherEvolutions(QRunnable): evolutions = {} for pokemon_form in all_pokemon_forms: - print(f"Processing {get_display_name(pokemon_form)}'s evolutions") - pokemon_name = pokemon_form["name"] - form = get_form_name(pokemon_form) - - if pokemon_form["form_name"] and any(s in pokemon_form["form_name"] for s in non_evolution_forms): + + evolution_tree = self.gather_evolution_tree(pokemon_form, force_refresh) + if not evolution_tree: continue - cache_record_name = f"chain_{pokemon_name}_{form}" - if force_refresh: - cache.purge(cache_record_name) - - cached_entry = cache.get(cache_record_name) - if cached_entry != None: - evolutions = evolutions | cached_entry - continue - - #form = get_form_name(pokemon_form, not pokemon_form["gender_relevant"]) - search_form = form - if search_form and pokemon_name in search_form: - search_form = search_form.replace(pokemon_name, "").strip() - gender = None + search_form = get_form_name(pokemon_form) if search_form and "male" in search_form.lower(): if "female" in search_form.lower(): - search_form = search_form.replace("Female", "").replace("female", "").strip() gender = "Female" else: - search_form = search_form.replace("Male", "").replace("male", "").strip() gender = "Male" - if search_form == "": - search_form = None + cacheable_container = {} + self.traverse_and_store(evolution_tree, cacheable_container, gender) - if pokemon_name == "Flabébé": - # Bulbapedia doesn't detail out Flabébé's evolution chain fully. as its exactly the same for each form, but the coloured form remains constant - # through the evolution line, Red->Red->Red, Yellow->Yellow->Yellow etc. - search_form = None + evolutions = evolutions | cacheable_container - url = f"https://bulbapedia.bulbagarden.net/wiki/{pokemon_name}_(Pokémon)" - page_data = cache.fetch_url(url) - if not page_data: - continue + print(self.evolution_methods) + return evolutions + + def gather_evolution_tree(self, pokemon_form, force_refresh = False): + print(f"Processing {get_display_name(pokemon_form)}'s evolutions") + pokemon_name = pokemon_form["name"] + form = get_form_name(pokemon_form) - soup = BeautifulSoup(page_data, 'html.parser') - evolution_section = soup.find('span', id='Evolution_data') - if not evolution_section: - continue + if pokemon_form["form_name"] and any(s in pokemon_form["form_name"] for s in non_evolution_forms): + return None - evolution_table = None - evolution_table = evolution_section.parent.find_next('table') - if form: - form_without_form = form.replace('Form', '').replace('form', '').strip() - form_without_form = self.strip_gender_from_form(form_without_form) - for tag in evolution_section.parent.find_next_siblings(): - if tag.name == 'h4' and form_without_form in tag.get_text(strip=True): - evolution_table = tag.find_next('table') - break - if tag.name == 'h3': - break - if not evolution_table: - continue - - evolution_tree = None - if pokemon_name == "Eevee": - evolution_tree = self.parse_eevee_evolution_chain(evolution_table, pokemon_form) + cache_record_name = f"chain_{pokemon_name}_{form}" + if force_refresh: + cache.purge(cache_record_name) + + cached_entry = cache.get(cache_record_name) + if cached_entry != None: + return cached_entry + search_form = form + if search_form and pokemon_name in search_form: + search_form = search_form.replace(pokemon_name, "").strip() + + if search_form and "male" in search_form.lower(): + if "female" in search_form.lower(): + search_form = search_form.replace("Female", "").replace("female", "").strip() else: - evolution_tree = self.parse_evolution_chain(evolution_table, pokemon_form) - - if evolution_tree["pokemon"] == "Milcery": - evolution_tree["evolves_to"] = [] - for alcremie_form in alcremie_forms: - node = { - "pokemon": "Alcremie", - "form": alcremie_form, - "requirement": None, - "method": "Complicated", - "evolves_to": [], - "stage": 1 - } - evolution_tree["evolves_to"].append(node) - - if evolution_tree["pokemon"] == "Flabébé": - def fix_form(node, new_form): - node["form"] = new_form - for next in node["evolves_to"]: - fix_form(next, new_form) - - flower_form = get_form_name(pokemon_form) - if "female" in flower_form.lower(): - flower_form = flower_form.replace("Female", "").replace("female", "").strip() - else: - flower_form = flower_form.replace("Male", "").replace("male", "").strip() - fix_form(evolution_tree, flower_form) + search_form = search_form.replace("Male", "").replace("male", "").strip() - cacheable_container = {} - if evolution_tree: - self.traverse_and_store(evolution_tree, cacheable_container, gender) + if search_form == "": + search_form = None - cache.set(cache_record_name, cacheable_container) - evolutions = evolutions | cacheable_container + if pokemon_name == "Flabébé": + # Bulbapedia doesn't detail out Flabébé's evolution chain fully. as its exactly the same for each form, but the coloured form remains constant + # through the evolution line, Red->Red->Red, Yellow->Yellow->Yellow etc. + search_form = None - print(self.evolution_methods) - return evolutions + url = f"https://bulbapedia.bulbagarden.net/wiki/{pokemon_name}_(Pokémon)" + page_data = cache.fetch_url(url) + if not page_data: + return None + + soup = BeautifulSoup(page_data, 'html.parser') + evolution_section = soup.find('span', id='Evolution_data') + if not evolution_section: + return None + + evolution_table = None + evolution_table = evolution_section.parent.find_next('table') + if form: + form_without_form = form.replace('Form', '').replace('form', '').strip() + form_without_form = self.strip_gender_from_form(form_without_form) + for tag in evolution_section.parent.find_next_siblings(): + if tag.name == 'h4' and form_without_form in tag.get_text(strip=True): + evolution_table = tag.find_next('table') + break + if tag.name == 'h3': + break + if not evolution_table: + return None + + evolution_tree = None + if pokemon_name == "Eevee": + evolution_tree = self.parse_eevee_evolution_chain(evolution_table, pokemon_form) + else: + evolution_tree = self.parse_evolution_chain(evolution_table, pokemon_form, force_refresh) + + if evolution_tree["pokemon"] == "Milcery": + evolution_tree["evolves_to"] = [] + for alcremie_form in alcremie_forms: + node = { + "pokemon": "Alcremie", + "form": alcremie_form, + "requirement": None, + "method": "Complicated", + "evolves_to": [], + "stage": 1 + } + evolution_tree["evolves_to"].append(node) + + if evolution_tree["pokemon"] == "Flabébé": + def fix_form(node, new_form): + node["form"] = new_form + for next in node["evolves_to"]: + fix_form(next, new_form) + + flower_form = get_form_name(pokemon_form) + if "female" in flower_form.lower(): + flower_form = flower_form.replace("Female", "").replace("female", "").strip() + else: + flower_form = flower_form.replace("Male", "").replace("male", "").strip() + fix_form(evolution_tree, flower_form) + + cache.set(cache_record_name, evolution_tree) + + return evolution_tree def traverse_and_store(self, node, evolutions, gender): """Helper function to traverse evolution tree and store evolutions.""" @@ -180,8 +190,11 @@ class GatherEvolutions(QRunnable): evolution_form = self.extract_evolution_form(td, pokemon_name) stage = self.extract_stage_form(td).replace("Evolution", "").replace("evolution", "").strip() numberical_stage = -1 + is_baby = False if stage == "Unevolved" or stage == "Baby form": numberical_stage = 0 + if stage == "Baby form": + is_baby = True elif stage == "Castoff": numberical_stage = 1 else: @@ -192,7 +205,8 @@ class GatherEvolutions(QRunnable): "requirement": None, "method": None, "evolves_to": [], - "stage": numberical_stage + "stage": numberical_stage, + "is_baby": is_baby } # Parse main evolution chain @@ -315,7 +329,8 @@ class GatherEvolutions(QRunnable): "pokemon": pokemon_name, "form": None, "method": None, - "evolves_to": [] + "evolves_to": [], + "is_baby": False } rows = tbody.find_all('tr', recursive=False) diff --git a/ui/workers/generate_plan_worker.py b/ui/workers/generate_plan_worker.py index 6bd1d37..bbda6b0 100644 --- a/ui/workers/generate_plan_worker.py +++ b/ui/workers/generate_plan_worker.py @@ -48,7 +48,7 @@ class GeneratePlanWorker(QRunnable): for home_pokemon in storable_in_home: found = False for game in self.game_plan: - if home_pokemon["PFIC"] in game["pokemon_map"]: + if home_pokemon["pfic"] in game["pokemon_map"]: found = True break if not found: diff --git a/utility/data.py b/utility/data.py index a61ee6e..3f88145 100644 --- a/utility/data.py +++ b/utility/data.py @@ -354,7 +354,8 @@ default_forms = [ "Overcast Form", "West Sea", "Normal", - "Red-Striped Form", + "Red Striped Form", + "Red-Striped Form", "Spring Form", "Incarnate Forme", "Meadow Pattern", diff --git a/utility/functions.py b/utility/functions.py index 5f0057d..9fdb8c3 100644 --- a/utility/functions.py +++ b/utility/functions.py @@ -16,8 +16,8 @@ def compare_pokemon_forms(a, b): if a == None or b == None: return False - temp_a = a.lower().replace("forme", "").replace("form", "").replace("é", "e").strip() - temp_b = b.lower().replace("forme", "").replace("form", "").replace("é", "e").strip() + temp_a = a.lower().replace("forme", "").replace("form", "").replace("é", "e").replace("-", " ").strip() + temp_b = b.lower().replace("forme", "").replace("form", "").replace("é", "e").replace("-", " ").strip() # Common spelling mistakes temp_a = temp_a.replace("deputante", "debutante").replace("p'au", "pa'u").replace("blood moon", "bloodmoon")