From e7442bc3baa2ba6dfa693263bc29f0b5a800a060 Mon Sep 17 00:00:00 2001 From: Quildra Date: Wed, 16 Oct 2024 22:07:17 +0100 Subject: [PATCH] - Add a right click to a row to allow for faster and more targettted freshing now --- DBEditor/DBEditor.py | 99 +++++--- DataGatherers/DetermineOriginGame.py | 8 +- DataGatherers/update_location_information.py | 225 ++++++++++++------- 3 files changed, 221 insertions(+), 111 deletions(-) diff --git a/DBEditor/DBEditor.py b/DBEditor/DBEditor.py index efee267..4545950 100644 --- a/DBEditor/DBEditor.py +++ b/DBEditor/DBEditor.py @@ -1,13 +1,20 @@ import sys from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QListWidget, QLineEdit, QLabel, QCheckBox, QPushButton, QFormLayout, QListWidgetItem, QSplitter, QTreeWidget, - QTreeWidgetItem, QDialog, QDialogButtonBox, QComboBox, QMessageBox, QSpinBox, QTabWidget) + QTreeWidgetItem, QDialog, QDialogButtonBox, QComboBox, QMessageBox, QSpinBox, QMenu) from PyQt6.QtCore import Qt, QSize -from PyQt6.QtGui import QPixmap, QFontMetrics, QColor +from PyQt6.QtGui import QPixmap, QFontMetrics, QColor, QAction import sqlite3 import json import os +# Add the parent directory to the Python path +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +# Now try to import +from DataGatherers.update_location_information import process_pokemon_for_location_data +from DataGatherers.cache_manager import CacheManager + class EvolutionEditDialog(QDialog): def __init__(self, parent=None, from_pfic=None, to_pfic=None, method=None): super().__init__(parent) @@ -237,16 +244,7 @@ class DBEditor(QMainWindow): def init_ui(self): central_widget = QWidget() self.setCentralWidget(central_widget) - main_layout = QVBoxLayout(central_widget) - - # Create a tab widget - self.tab_widget = QTabWidget() - main_layout.addWidget(self.tab_widget) - - # Main tab - main_tab = QWidget() - main_tab_layout = QHBoxLayout(main_tab) - self.tab_widget.addTab(main_tab, "Main") + main_layout = QHBoxLayout(central_widget) # Left side: Search and List left_layout = QVBoxLayout() @@ -259,13 +257,17 @@ class DBEditor(QMainWindow): left_layout.addLayout(search_layout) self.pokemon_list = QListWidget() + self.pokemon_list.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) + self.pokemon_list.customContextMenuRequested.connect(self.show_pokemon_context_menu) self.pokemon_list.currentItemChanged.connect(self.load_pokemon_details) left_layout.addWidget(self.pokemon_list) + # Move the checkbox here, after the pokemon_list self.highlight_no_encounters = QCheckBox("Highlight Pokémon without encounters") self.highlight_no_encounters.stateChanged.connect(self.toggle_highlight_mode) left_layout.addWidget(self.highlight_no_encounters) + # Add the new checkbox for filtering Home-storable Pokémon self.filter_home_storable = QCheckBox("Show only Home-storable Pokémon") self.filter_home_storable.stateChanged.connect(self.filter_pokemon_list) left_layout.addWidget(self.filter_home_storable) @@ -336,20 +338,8 @@ class DBEditor(QMainWindow): right_layout.addLayout(text_layout) right_layout.addLayout(image_layout) - main_tab_layout.addLayout(left_layout, 1) - main_tab_layout.addLayout(right_layout, 1) - - # Advanced tab - advanced_tab = QWidget() - advanced_tab_layout = QVBoxLayout(advanced_tab) - self.tab_widget.addTab(advanced_tab, "Advanced") - - # Add Manage Exclusive Groups button to the Advanced tab - manage_groups_button = QPushButton("Manage Exclusive Encounter Groups") - manage_groups_button.clicked.connect(self.manage_exclusive_groups) - advanced_tab_layout.addWidget(manage_groups_button) - - # Add more advanced features here as needed + main_layout.addLayout(left_layout, 1) + main_layout.addLayout(right_layout, 1) self.load_pokemon_list() @@ -1000,6 +990,63 @@ class DBEditor(QMainWindow): self.conn.commit() group_list.takeItem(group_list.row(item)) + def show_pokemon_context_menu(self, position): + item = self.pokemon_list.itemAt(position) + if item is not None: + context_menu = QMenu(self) + refresh_action = QAction("Refresh Encounters", self) + refresh_action.triggered.connect(lambda: self.refresh_pokemon_encounters(item)) + context_menu.addAction(refresh_action) + context_menu.exec(self.pokemon_list.viewport().mapToGlobal(position)) + + def refresh_pokemon_encounters(self, item): + pfic = item.data(Qt.ItemDataRole.UserRole) + self.cursor.execute(''' + SELECT name, form_name, national_dex + FROM pokemon_forms + WHERE PFIC = ? + ''', (pfic,)) + pokemon_data = self.cursor.fetchone() + if pokemon_data: + name, form, national_dex = pokemon_data + + # Import the necessary function and classes + #from DataGatherers.update_location_information import process_pokemon_for_location_data + + import json + + # Create a temporary connection for this operation + temp_conn = sqlite3.connect('pokemon_forms.db') + + # Load default forms + try: + with open('./DataGatherers/DefaultForms.json', 'r') as f: + default_forms = json.load(f) + except FileNotFoundError: + default_forms = [] + + # Create a cache manager instance + cache = CacheManager() + + # Delete existing encounters for this Pokémon + self.cursor.execute('DELETE FROM encounters WHERE pfic = ?', (pfic,)) + self.conn.commit() + + # Process the Pokémon data + process_pokemon_for_location_data(pfic, name, form, national_dex, default_forms, cache, temp_conn) + + # Close the temporary connection + temp_conn.close() + + # Refresh the encounter locations in the UI + self.load_encounter_locations(pfic) + + # Update the encounter cache and highlights + self.update_encounter_cache() + self.update_pokemon_list_highlights() + + print(f"Refreshed encounters for {name} {form if form else ''}") + if __name__ == '__main__': app = QApplication(sys.argv) editor = DBEditor() diff --git a/DataGatherers/DetermineOriginGame.py b/DataGatherers/DetermineOriginGame.py index f4c8217..00f9d1a 100644 --- a/DataGatherers/DetermineOriginGame.py +++ b/DataGatherers/DetermineOriginGame.py @@ -13,7 +13,13 @@ from fuzzywuzzy import fuzz from fuzzywuzzy import process from collections import defaultdict -from cache_manager import CacheManager +import os +import sys + +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + + +from DataGatherers.cache_manager import CacheManager # List of all main series Pokémon games in chronological order, with special games first in each generation all_games = [ diff --git a/DataGatherers/update_location_information.py b/DataGatherers/update_location_information.py index 92b5d56..27adae7 100644 --- a/DataGatherers/update_location_information.py +++ b/DataGatherers/update_location_information.py @@ -1,7 +1,12 @@ +import os +import sys + +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + import json import sqlite3 -from cache_manager import CacheManager -from DetermineOriginGame import get_locations_from_bulbapedia +from DataGatherers.cache_manager import CacheManager +from DataGatherers.DetermineOriginGame import get_locations_from_bulbapedia from bs4 import BeautifulSoup, Tag import re import time @@ -204,26 +209,77 @@ def extract_additional_information(s): def save_encounter(conn, pfic, game, location, days, times, dual_slot, static_encounter, static_encounter_count, extra_text, stars, rods, fishing, starter): cursor = conn.cursor() + + # Convert lists to strings for comparison, except days and times + extra_text_str = ' '.join(extra_text) if extra_text else None + stars_str = ','.join(sorted(stars)) if stars else None + rods_str = ','.join(sorted(rods)) if rods else None + if len(days) > 0: for day in days: + # Check if an identical record already exists cursor.execute(''' - INSERT OR REPLACE INTO encounters - (pfic, game, location, day, time, dual_slot, static_encounter_count, static_encounter, extra_text, stars, rods, fishing, starter) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - ''', (pfic, game, location, day, None, dual_slot, static_encounter_count, static_encounter, ' '.join(extra_text), ','.join(stars), ','.join(rods), fishing, starter)) + SELECT COUNT(*) FROM encounters + WHERE pfic = ? AND game = ? AND location = ? AND day = ? AND time IS NULL + AND dual_slot = ? AND static_encounter = ? AND static_encounter_count = ? + AND extra_text = ? AND stars = ? AND rods = ? AND fishing = ? AND starter = ? + ''', (pfic, game, location, day, dual_slot, static_encounter, + static_encounter_count, extra_text_str, stars_str, rods_str, fishing, starter)) + + if cursor.fetchone()[0] == 0: + cursor.execute(''' + INSERT INTO encounters + (pfic, game, location, day, time, dual_slot, static_encounter_count, static_encounter, extra_text, stars, rods, fishing, starter) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ''', (pfic, game, location, day, None, dual_slot, static_encounter_count, + static_encounter, extra_text_str, stars_str, rods_str, fishing, starter)) + print(f"New encounter added for {pfic} in {game} at {location} on {day}") + else: + print(f"Identical encounter already exists for {pfic} in {game} at {location} on {day}") + elif len(times) > 0: for time in times: + # Check if an identical record already exists cursor.execute(''' - INSERT OR REPLACE INTO encounters - (pfic, game, location, day, time, dual_slot, static_encounter_count, static_encounter, extra_text, stars, rods, fishing, starter) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - ''', (pfic, game, location, None, time, dual_slot, static_encounter_count, static_encounter, ' '.join(extra_text), ','.join(stars), ','.join(rods), fishing, starter)) + SELECT COUNT(*) FROM encounters + WHERE pfic = ? AND game = ? AND location = ? AND day IS NULL AND time = ? + AND dual_slot = ? AND static_encounter = ? AND static_encounter_count = ? + AND extra_text = ? AND stars = ? AND rods = ? AND fishing = ? AND starter = ? + ''', (pfic, game, location, time, dual_slot, static_encounter, + static_encounter_count, extra_text_str, stars_str, rods_str, fishing, starter)) + + if cursor.fetchone()[0] == 0: + cursor.execute(''' + INSERT INTO encounters + (pfic, game, location, day, time, dual_slot, static_encounter_count, static_encounter, extra_text, stars, rods, fishing, starter) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ''', (pfic, game, location, None, time, dual_slot, static_encounter_count, + static_encounter, extra_text_str, stars_str, rods_str, fishing, starter)) + print(f"New encounter added for {pfic} in {game} at {location} at {time}") + else: + print(f"Identical encounter already exists for {pfic} in {game} at {location} at {time}") + else: + # Check if an identical record already exists cursor.execute(''' - INSERT OR REPLACE INTO encounters + SELECT COUNT(*) FROM encounters + WHERE pfic = ? AND game = ? AND location = ? AND day IS NULL AND time IS NULL + AND dual_slot = ? AND static_encounter = ? AND static_encounter_count = ? + AND extra_text = ? AND stars = ? AND rods = ? AND fishing = ? AND starter = ? + ''', (pfic, game, location, dual_slot, static_encounter, + static_encounter_count, extra_text_str, stars_str, rods_str, fishing, starter)) + thing = cursor.fetchone() + if thing[0] == 0: + cursor.execute(''' + INSERT INTO encounters (pfic, game, location, day, time, dual_slot, static_encounter_count, static_encounter, extra_text, stars, rods, fishing, starter) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - ''', (pfic, game, location, None, None, dual_slot, static_encounter_count, static_encounter, ' '.join(extra_text), ','.join(stars), ','.join(rods), fishing, starter)) + ''', (pfic, game, location, None, None, dual_slot, static_encounter_count, + static_encounter, extra_text_str, stars_str, rods_str, fishing, starter)) + print(f"New encounter added for {pfic} in {game} at {location}") + else: + print(f"Identical encounter already exists for {pfic} in {game} at {location}") + conn.commit() def compare_forms(a, b): @@ -241,6 +297,77 @@ def compare_forms(a, b): return False +def process_pokemon_for_location_data(pfic, name, form, national_dex, default_forms, cache, conn): + print(f"Processing {name} {form if form else ''}") + + if form and name in form: + form = form.replace(name, "").strip() + + if form and form in default_forms: + form = None + + if name == "Unown" and (form != "!" and form != "?"): + form = None + + if name == "Tauros" and form == "Combat Breed": + form = "Paldean Form" + + if name == "Alcremie": + form = None + + if form and form.lower() == "female": + form = None + + search_form = form + + encounters_to_ignore = ["trade", "time capsule", "unobtainable", "evolve", "tradeversion", "poké transfer", "friend safari", "unavailable", "pokémon home"] + + encounter_data = get_locations_from_bulbapedia(name, search_form, cache, default_forms) + if encounter_data == None: + return + + for encounter in encounter_data: + if len(encounter_data[encounter]) == 0: + return + + print_encounter = True + + for location in encounter_data[encounter]: + if location == "": + return + test_location = location["location"].strip().lower() + + ignore_location = False + for ignore in encounters_to_ignore: + if ignore in test_location: + ignore_location = True + break + + if ignore_location: + return + + if print_encounter: + print(f"Found in {encounter}:") + print_encounter = False + + remaining, details = extract_additional_information(location["tag"]) + routes, remaining = extract_routes(remaining) + print(f"Routes: {routes}") + print(f"Remaining: {remaining.strip()}") + print(f"Details: {details}") + + if len(details["times"]) > 0: + print("Stupid Data") + + for route in routes: + route_name = f"Route {route}" + save_encounter(conn, pfic, encounter, route_name, details["days"], details["times"], details["dual_slot"], details["static_encounter"], details["static_encounter_count"], details["extra_text"], details["stars"], details["Rods"], details["Fishing"], details["starter"] ) + + if remaining != "": + remaining_locations = remaining.replace(" and ", ",").split(",") + for remaining_location in remaining_locations: + save_encounter(conn, pfic, encounter, remaining_location.strip(), details["days"], details["times"], details["dual_slot"], details["static_encounter"], details["static_encounter_count"], details["extra_text"], details["stars"], details["Rods"], details["Fishing"], details["starter"] ) + if __name__ == "__main__": cache = CacheManager() @@ -260,76 +387,6 @@ if __name__ == "__main__": default_forms = [] for pfic, name, form, national_dex in pokemon_forms: - print(f"Processing {name} {form if form else ''}") - - if form and name in form: - form = form.replace(name, "").strip() - - if form and form in default_forms: - form = None - - if name == "Unown" and (form != "!" and form != "?"): - form = None - - if name == "Tauros" and form == "Combat Breed": - form = "Paldean Form" - - if name == "Alcremie": - form = None - - if form and form.lower() == "female": - form = None - - search_form = form - # unrecognized_forms = ["Unown", "Zacian", "Zamazenta"] - # if name in unrecognized_forms: - # search_form = None - - encounters_to_ignore = ["trade", "time capsule", "unobtainable", "evolve", "tradeversion", "poké transfer", "friend safari", "unavailable", "pokémon home"] - - encounter_data = get_locations_from_bulbapedia(name, search_form, cache, default_forms) - if encounter_data == None: - continue - - for encounter in encounter_data: - if len(encounter_data[encounter]) == 0: - continue - - print_encounter = True - - for location in encounter_data[encounter]: - if location == "": - continue - test_location = location["location"].strip().lower() - - ignore_location = False - for ignore in encounters_to_ignore: - if ignore in test_location: - ignore_location = True - break - - if ignore_location: - continue - - if print_encounter: - print(f"Found in {encounter}:") - print_encounter = False - - remaining, details = extract_additional_information(location["tag"]) - routes, remaining = extract_routes(remaining) - print(f"Routes: {routes}") - print(f"Remaining: {remaining.strip()}") - print(f"Details: {details}") - - if len(details["times"]) > 0: - print("Stupid Data") - - for route in routes: - route_name = f"Route {route}" - save_encounter(conn, pfic, encounter, route_name, details["days"], details["times"], details["dual_slot"], details["static_encounter"], details["static_encounter_count"], details["extra_text"], details["stars"], details["Rods"], details["Fishing"], details["starter"] ) - - if remaining != "": - remaining_locations = remaining.replace(" and ", ",").split(",") - for remaining_location in remaining_locations: - save_encounter(conn, pfic, encounter, remaining_location.strip(), details["days"], details["times"], details["dual_slot"], details["static_encounter"], details["static_encounter_count"], details["extra_text"], details["stars"], details["Rods"], details["Fishing"], details["starter"] ) + process_pokemon_for_location_data(pfic, name, form, national_dex, default_forms, cache, conn) + conn.close()