5 changed files with 850 additions and 5 deletions
@ -0,0 +1,699 @@ |
|||
from PyQt6.QtCore import QObject, pyqtSignal, QRunnable |
|||
from bs4 import BeautifulSoup, NavigableString |
|||
from pattern.en import singularize |
|||
from fuzzywuzzy import fuzz |
|||
import re |
|||
|
|||
from cache import cache |
|||
from db import db |
|||
|
|||
from utility.data import default_forms, regional_descriptors, days, times, rods |
|||
from utility.functions import is_mainline_game, compare_pokemon_forms, find_match_in_string_array, extract_bracketed_text |
|||
|
|||
class GatherEncountersWorkerSignals(QObject): |
|||
finished = pyqtSignal(list) |
|||
|
|||
class GatherEncountersWorker(QRunnable): |
|||
def __init__(self): |
|||
super().__init__() |
|||
self.signals = GatherEncountersWorkerSignals() |
|||
self.default_forms_set = set(default_forms) |
|||
self.encounters_to_ignore = [ |
|||
"trade", |
|||
"time capsule", |
|||
"unobtainable", |
|||
"tradeversion", |
|||
"poké transfer", |
|||
"friend safari", |
|||
"unavailable", |
|||
"pokémon home", |
|||
"union circle", |
|||
"pokémon bank", |
|||
"pal park", |
|||
"transfer from dream radar", |
|||
"global link event", |
|||
"pokémon channel", |
|||
"pokémon colosseum bonus disc" |
|||
] |
|||
self.encounters = [] |
|||
|
|||
def run(self): |
|||
try: |
|||
gathered_data = self.gather_encounter_data() |
|||
self.signals.finished.emit(gathered_data) |
|||
except Exception as e: |
|||
print(f"Error gathering Pokémon forms: {e}") |
|||
|
|||
def gather_encounter_data(self): |
|||
all_pokemon_forms = db.get_list_of_pokemon_forms() |
|||
|
|||
for form_entry in all_pokemon_forms: |
|||
form = form_entry["form_name"] |
|||
name = form_entry["name"] |
|||
pfic = form_entry["pfic"] |
|||
|
|||
print(f'Processing {name}') |
|||
|
|||
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 name == "Minior": |
|||
form = None |
|||
|
|||
if name.lower() == "ho-oh": |
|||
name = "Ho-Oh" |
|||
|
|||
if form and form.startswith("Female"): |
|||
form = form.replace("Female", "").strip() |
|||
|
|||
if form and form.startswith("Male"): |
|||
form = form.replace("Male", "").strip() |
|||
|
|||
if form == "": |
|||
form = None |
|||
|
|||
search_form = form |
|||
|
|||
encounter_data = self.get_locations_from_bulbapedia(name, search_form) |
|||
if encounter_data == None: |
|||
continue |
|||
|
|||
for encounter in encounter_data: |
|||
if len(encounter_data[encounter]) == 0: |
|||
break |
|||
|
|||
for location in encounter_data[encounter]: |
|||
if location == "": |
|||
continue |
|||
test_location = location["location"].strip().lower() |
|||
test_location_text = BeautifulSoup(test_location, 'html.parser').get_text().lower() |
|||
if "evolve" in test_location_text: |
|||
remaining, details = self.extract_additional_information(location["tag"]) |
|||
evolve_info = self.extract_evolve_information(remaining) |
|||
|
|||
if evolve_info: |
|||
#logger.info(f"Evolve Info: {evolve_info}") |
|||
self.save_evolve_encounter(pfic, encounter, details["days"], details["times"], evolve_info["evolve_from"]) |
|||
elif "event" in test_location_text: |
|||
#logger.info(f"Event: {location['location']}") |
|||
self.save_event_encounter(pfic, encounter) |
|||
else: |
|||
remaining, details = self.extract_additional_information(location["tag"]) |
|||
routes, remaining = self.extract_routes(remaining) |
|||
#logger.info(f"Routes: {routes}") |
|||
#logger.info(f"Remaining: {remaining.strip()}") |
|||
#logger.info(f"Details: {details}") |
|||
|
|||
if len(details["times"]) > 0: |
|||
#logger.info("Stupid Data") |
|||
pass |
|||
|
|||
for route in routes: |
|||
route_name = f"Route {route}" |
|||
self.save_encounter(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: |
|||
if remaining_location.strip() == "": |
|||
continue |
|||
|
|||
ignore_location = False |
|||
for ignore in self.encounters_to_ignore: |
|||
if ignore in remaining_location.lower(): |
|||
ignore_location = True |
|||
break |
|||
|
|||
if ignore_location: |
|||
continue |
|||
|
|||
self.save_encounter(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"] ) |
|||
|
|||
return self.encounters |
|||
|
|||
|
|||
def get_locations_from_bulbapedia(self, pokemon_name, form, force_refresh = False): |
|||
url = f"https://bulbapedia.bulbagarden.net/wiki/{pokemon_name}_(Pokémon)" |
|||
page_data = cache.fetch_url(url) |
|||
if not page_data: |
|||
return None |
|||
|
|||
cache_key = f'locations_{url}_data' |
|||
|
|||
if force_refresh: |
|||
cache.purge(cache_key) |
|||
|
|||
cached_entry = cache.get(cache_key) |
|||
if cached_entry != None: |
|||
return cached_entry |
|||
|
|||
soup = BeautifulSoup(page_data, 'html.parser') |
|||
if not soup: |
|||
return None |
|||
|
|||
# Try different methods to find the locations table |
|||
locations_table = None |
|||
possible_headers = ['Game locations', 'In side games', 'In spin-off games'] |
|||
|
|||
for header in possible_headers: |
|||
span = soup.find('span', id=header.replace(' ', '_')) |
|||
if span: |
|||
locations_table = span.find_next('table', class_='roundy') |
|||
if locations_table: |
|||
break |
|||
|
|||
if not locations_table: |
|||
print(f"Warning: Couldn't find locations table for {pokemon_name}") |
|||
return None |
|||
|
|||
raw_game_locations = {} |
|||
|
|||
generation_tbody = locations_table.find('tbody', recursive=False) |
|||
generation_rows = generation_tbody.find_all('tr', recursive=False) |
|||
for generation_row in generation_rows: |
|||
random_nested_td = generation_row.find('td', recursive=False) |
|||
if not random_nested_td: |
|||
continue |
|||
random_nested_table = random_nested_td.find('table', recursive=False) |
|||
if not random_nested_table: |
|||
continue |
|||
random_nested_tbody = random_nested_table.find('tbody', recursive=False) |
|||
random_nested_rows = random_nested_tbody.find_all('tr', recursive=False) |
|||
|
|||
for nested_row in random_nested_rows: |
|||
if 'Generation' in nested_row.get_text(strip=True): |
|||
continue |
|||
|
|||
games_container_td = nested_row.find('td', recursive=False) |
|||
if not games_container_td: |
|||
continue |
|||
games_container_table = games_container_td.find('table', recursive=False) |
|||
if not games_container_table: |
|||
continue |
|||
games_container_tbody = games_container_table.find('tbody', recursive=False) |
|||
games_container_rows = games_container_tbody.find_all('tr', recursive=False) |
|||
for games_container_row in games_container_rows: |
|||
games = games_container_row.find_all('th') |
|||
for game in games: |
|||
raw_game = game.get_text(strip=True) |
|||
if is_mainline_game(raw_game) == None: |
|||
continue |
|||
locations_container_td = games_container_row.find('td', recursive=False) |
|||
if not locations_container_td: |
|||
continue |
|||
locations_container_table = locations_container_td.find('table', recursive=False) |
|||
if not locations_container_table: |
|||
continue |
|||
locations_container_tbody = locations_container_table.find('tbody', recursive=False) |
|||
locations = locations_container_tbody.find_all('td') |
|||
for location in locations: |
|||
groups = self.split_td_contents(location) |
|||
for group in groups: |
|||
if raw_game not in raw_game_locations: |
|||
raw_game_locations[raw_game] = [] |
|||
raw_game_locations[raw_game].append(group) |
|||
|
|||
# Process events |
|||
events_section = soup.find('span', id='In_events') |
|||
event_tables = self.process_event_tables(events_section) if events_section else {} |
|||
|
|||
game_locations = {} |
|||
for raw_game, raw_locations in raw_game_locations.items(): |
|||
encounters = self.process_game_locations(raw_game, raw_locations, form) |
|||
if encounters and len(encounters) > 0: |
|||
game_locations[raw_game] = encounters |
|||
|
|||
# Process event tables |
|||
for variant in event_tables: |
|||
if (variant == pokemon_name and form is None) or (form and form in variant): |
|||
self.process_event_table(event_tables[variant], game_locations) |
|||
|
|||
cache.set(cache_key, game_locations) |
|||
return game_locations |
|||
|
|||
def split_td_contents(self, td): |
|||
groups = [] |
|||
current_group = [] |
|||
for content in td.contents: |
|||
if isinstance(content, NavigableString): |
|||
text = content.strip() |
|||
if text: |
|||
current_group.append(content) |
|||
elif content.name == 'br': |
|||
if current_group: |
|||
groups.append(''.join(str(item) for item in current_group)) |
|||
current_group = [] |
|||
else: |
|||
current_group.append(content) |
|||
if current_group: |
|||
groups.append(''.join(str(item) for item in current_group)) |
|||
return groups |
|||
|
|||
def process_game_locations(self, raw_game, raw_locations, form): |
|||
locations = [] |
|||
|
|||
for raw_location in raw_locations: |
|||
raw_text = raw_location |
|||
forms = self.parse_form_information(raw_location) |
|||
if form is None: |
|||
if len(forms) > 0: |
|||
for form_info in forms: |
|||
main_form = form_info["main_form"] |
|||
if default_forms and main_form and main_form in self.default_forms_set: |
|||
main_form = None |
|||
|
|||
if main_form and (main_form != "All Forms" and main_form != "Kantonian Form" and main_form != "All Sizes"): |
|||
continue |
|||
|
|||
locations.append({"location": raw_text, "tag": raw_location}) |
|||
else: |
|||
locations.append({"location": raw_text, "tag": raw_location}) |
|||
elif len(forms) > 0: |
|||
for form_info in forms: |
|||
if self.form_matches(form_info, form, default_forms): |
|||
locations.append({"location": raw_text, "tag": raw_location}) |
|||
else: |
|||
form_info = {"main_form": None, "sub_form": None, "region": None} |
|||
if self.form_matches(form_info, form, default_forms): |
|||
locations.append({"location": raw_text, "tag": raw_location}) |
|||
|
|||
return locations if locations else None |
|||
|
|||
def process_event_tables(self, events_section): |
|||
event_tables = {} |
|||
if events_section: |
|||
next_element = events_section.parent.find_next_sibling() |
|||
while next_element and next_element.name != 'h3': |
|||
if next_element.name == 'h5': |
|||
variant = next_element.text.strip() |
|||
table = next_element.find_next_sibling('table', class_='roundy') |
|||
if table: |
|||
event_tables[variant] = table |
|||
next_element = next_element.find_next_sibling() |
|||
return event_tables |
|||
|
|||
def parse_form_information(self, html_content): |
|||
soup = BeautifulSoup(html_content, 'html.parser') |
|||
|
|||
#TODO: This wont work for lines that have several small blocks in one line. |
|||
#TODO: Adjust this to handle more than one small block, see Basculin for example |
|||
small_tag = soup.find('small') |
|||
|
|||
forms = [] |
|||
# Form info is in bold inside a small tag. |
|||
if small_tag: |
|||
bold_tags = small_tag.find_all('b') |
|||
for bold_tag in bold_tags: |
|||
form_text = bold_tag.get_text(strip=True) |
|||
|
|||
# Remove parentheses |
|||
form_text = form_text.strip('()') |
|||
|
|||
if "/" in form_text: |
|||
last_word = singularize(form_text.split()[-1]) |
|||
form_text = form_text.replace(last_word, "").strip() |
|||
parts = form_text.split('/') |
|||
for part in parts: |
|||
main_form = part.strip() + " " + last_word |
|||
info = { |
|||
"main_form": main_form, |
|||
"sub_form": None |
|||
} |
|||
forms.append(info) |
|||
continue |
|||
|
|||
# Split the text into main form and breed (if present) |
|||
parts = form_text.split('(') |
|||
main_form = parts[0].strip() |
|||
|
|||
# "Factor"s are not actual forms, they are properties of the pokemon you can encoutner. |
|||
if main_form and "factor" in main_form.lower(): |
|||
continue |
|||
|
|||
breed = parts[1].strip(')') if len(parts) > 1 else None |
|||
|
|||
info = { |
|||
"main_form": main_form, |
|||
"sub_form": breed |
|||
} |
|||
|
|||
for region in regional_descriptors: |
|||
if region in main_form.lower(): |
|||
info["region"] = region |
|||
break |
|||
|
|||
forms.append(info) |
|||
else: #..... Gimmighoul |
|||
headings = soup.find_all('b') |
|||
if len(headings) > 0: |
|||
for heading in headings: |
|||
if heading.parent.name == 'sup': |
|||
continue |
|||
if "form" not in heading.get_text(strip=True).lower(): |
|||
continue |
|||
main_form = heading.get_text(strip=True) |
|||
info = { |
|||
"main_form": main_form, |
|||
"sub_form": None |
|||
} |
|||
|
|||
for region in regional_descriptors: |
|||
if region in main_form.lower(): |
|||
info["region"] = region |
|||
break |
|||
|
|||
forms.append(info) |
|||
|
|||
return forms |
|||
|
|||
def form_matches(self, form_info, form, default_forms): |
|||
main_form = form_info["main_form"] |
|||
sub_form = form_info["sub_form"] |
|||
try: |
|||
region = form_info['region'] if 'region' in form_info else None |
|||
except KeyError: |
|||
region = None |
|||
|
|||
if default_forms and main_form and main_form in default_forms: |
|||
main_form = None |
|||
|
|||
if form.lower() in ["spring form", "summer form", "autumn form", "winter form"] and main_form == None: |
|||
return True |
|||
|
|||
if main_form is None: |
|||
return False |
|||
|
|||
if main_form in ["All Forms", "All Sizes"]: |
|||
return True |
|||
|
|||
if region == None and main_form in ["Kantonian Form"]: |
|||
return True |
|||
|
|||
main_form_match = compare_pokemon_forms(form, main_form) or fuzz.partial_ratio(form.lower(), main_form.lower()) >= 95 |
|||
sub_form_match = compare_pokemon_forms(form, sub_form) or (sub_form and fuzz.partial_ratio(form.lower(), sub_form.lower()) >= 95) |
|||
|
|||
if not main_form_match and not sub_form_match and region: |
|||
region_match = compare_pokemon_forms(form, region) or fuzz.partial_ratio(form.lower(), region.lower()) >= 95 |
|||
return region_match |
|||
|
|||
return main_form_match or sub_form_match |
|||
|
|||
def extract_routes(self, s): |
|||
# Find all route numbers, including those after "and" or separated by commas |
|||
route_pattern = r'Routes?\s+((?:\d+(?:,?\s+(?:and\s+)?)?)+)' |
|||
route_match = re.search(route_pattern, s, re.IGNORECASE) |
|||
|
|||
if route_match: |
|||
# Extract all numbers from the matched group |
|||
numbers = re.findall(r'\d+', route_match.group(1)) |
|||
|
|||
# Remove the extracted part from the original string |
|||
remaining = s[:route_match.start()] + s[route_match.end():].lstrip(', ') |
|||
|
|||
return numbers, remaining |
|||
else: |
|||
return [], s |
|||
|
|||
def extract_additional_information(self, s): |
|||
details = {} |
|||
details["days"] = [] |
|||
details["times"] = [] |
|||
details["dual_slot"] = None |
|||
details["static_encounter_count"] = 0 |
|||
details["static_encounter"] = False |
|||
details["starter"] = False |
|||
details["extra_text"] = [] |
|||
details["stars"] = [] |
|||
details["Fishing"] = False |
|||
details["Rods"] = [] |
|||
|
|||
if s is None: |
|||
return "", details |
|||
|
|||
soup = BeautifulSoup(s, 'html.parser') |
|||
full_text = soup.get_text() |
|||
sup_tags = soup.find_all('sup') |
|||
sup_text = [] |
|||
|
|||
if "first partner" in full_text.lower(): |
|||
details["starter"] = True |
|||
|
|||
for sup_tag in sup_tags: |
|||
text = sup_tag.get_text(strip=True) |
|||
|
|||
if find_match_in_string_array(text, days): |
|||
details["days"].append(text) |
|||
sup_text.append(text) |
|||
|
|||
if find_match_in_string_array(text, times): |
|||
details["times"].append(text) |
|||
sup_text.append(text) |
|||
|
|||
bracket_text = extract_bracketed_text(full_text) |
|||
|
|||
for text in bracket_text: |
|||
text = text.strip() |
|||
text_lower = text.lower() |
|||
|
|||
game = is_mainline_game(text_lower) |
|||
if game != None: |
|||
details["dual_slot"] = game["Name"] |
|||
text = re.sub(game["Name"], '', text_lower, flags=re.IGNORECASE) |
|||
|
|||
match = find_match_in_string_array(text_lower, days) |
|||
if match: |
|||
details["days"].append(match) |
|||
text = re.sub(match, '', text_lower, flags=re.IGNORECASE) |
|||
|
|||
match = find_match_in_string_array(text_lower, times) |
|||
if match: |
|||
details["times"].append(match) |
|||
text = re.sub(match, '', text_lower, flags=re.IGNORECASE) |
|||
|
|||
if "only one" in text_lower: |
|||
details["static_encounter_count"] = 1 |
|||
details["static_encounter"] = True |
|||
text = re.sub(r'only one', '', text_lower, flags=re.IGNORECASE) |
|||
elif "only two" in text_lower: |
|||
details["static_encounter_count"] = 2 |
|||
details["static_encounter"] = True |
|||
text = re.sub(r'only two', '', text_lower, flags=re.IGNORECASE) |
|||
|
|||
if "rod" in text_lower: |
|||
match = find_match_in_string_array(text_lower, rods) |
|||
if match: |
|||
details["Fishing"] = True |
|||
details["Rods"].append(match) |
|||
text = re.sub(match, '', text_lower, flags=re.IGNORECASE) |
|||
|
|||
if "★" in text: |
|||
star_parts = re.findall(r'\d★,*', text) |
|||
for part in star_parts: |
|||
details["stars"].append(part.replace(',', '').strip()) |
|||
text = re.sub(r'\d★,*', '', text) |
|||
|
|||
if text.strip() != "": |
|||
details["extra_text"].append(text.strip()) |
|||
sup_text.append(text.strip()) |
|||
|
|||
if len(sup_text) > 0: |
|||
for text in sup_text: |
|||
full_text = full_text.replace(text, "") |
|||
|
|||
if len(bracket_text) > 0: |
|||
for text in bracket_text: |
|||
full_text = full_text.replace(text, "") |
|||
full_text = full_text.replace('(', "").replace(')', "") |
|||
|
|||
return full_text.strip(), details |
|||
else: |
|||
return full_text, details |
|||
|
|||
def extract_evolve_information(self, s: str): |
|||
details = {} |
|||
if s is None or s == "": |
|||
return details |
|||
|
|||
s = s.replace("Evolve", "") |
|||
|
|||
parts = s.split(" ") |
|||
|
|||
if len(parts) >= 1: |
|||
target_pokemon = parts[0].strip() |
|||
|
|||
form = None |
|||
if "♀" in target_pokemon: |
|||
target_pokemon = target_pokemon.replace("♀", "").strip() |
|||
form = "Female" |
|||
|
|||
if "♂" in target_pokemon: |
|||
target_pokemon = target_pokemon.replace("♂", "").strip() |
|||
form = "Male" |
|||
|
|||
results = db.get_pokemon_details_by_name(target_pokemon) |
|||
|
|||
if results: |
|||
for result in results: |
|||
if compare_pokemon_forms(result["form_name"], form): |
|||
details["evolve_from"] = result["pfic"] |
|||
|
|||
return details |
|||
|
|||
def save_evolve_encounter(self, pfic, game, days, times, from_pfic): |
|||
game_id = db.get_game_id_by_name(game) |
|||
|
|||
encounter = { |
|||
"pfic": pfic, |
|||
"game_id": game_id, |
|||
"type": "evolve", |
|||
"data": { |
|||
"day": None, |
|||
"time": None, |
|||
"from_pfic": from_pfic, |
|||
} |
|||
} |
|||
|
|||
if len(days) > 0: |
|||
for day in days: |
|||
encounter["data"]["day"] = day |
|||
encounter["data"]["time"] = None |
|||
self.encounters.append(encounter) |
|||
|
|||
elif len(times) > 0: |
|||
for time in times: |
|||
encounter["data"]["day"] = None |
|||
encounter["data"]["time"] = time |
|||
self.encounters.append(encounter) |
|||
else: |
|||
encounter["data"]["day"] = None |
|||
encounter["data"]["time"] = None |
|||
self.encounters.append(encounter) |
|||
|
|||
def save_event_encounter(self, pfic, game): |
|||
game_id = db.get_game_id_by_name(game) |
|||
|
|||
encounter = { |
|||
"pfic": pfic, |
|||
"game_id": game_id, |
|||
"type": "event" |
|||
} |
|||
|
|||
self.encounters.append(encounter) |
|||
|
|||
def save_encounter(self, pfic, game, location, days, times, dual_slot, static_encounter, static_encounter_count, extra_text, stars, rods, fishing, starter): |
|||
game_id = db.get_game_id_by_name(game) |
|||
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 |
|||
|
|||
encounter_type = "random" |
|||
|
|||
if starter: |
|||
encounter_type = "starter" |
|||
|
|||
if static_encounter: |
|||
encounter_type = "static" |
|||
|
|||
encounter = { |
|||
"pfic": pfic, |
|||
"game_id": game_id, |
|||
"type": encounter_type, |
|||
"data": { |
|||
"location": location, |
|||
"day": None, |
|||
"time": None, |
|||
"dual_slot": dual_slot, |
|||
"extra_text": extra_text_str, |
|||
"stars": stars_str, |
|||
"rods": rods_str, |
|||
"fishing": fishing |
|||
} |
|||
} |
|||
|
|||
if static_encounter: |
|||
encounter["data"]["static_encounter_count"] = static_encounter_count |
|||
|
|||
if len(days) > 0: |
|||
for day in days: |
|||
encounter["data"]["day"] = day |
|||
encounter["data"]["time"] = None |
|||
self.encounters.append(encounter) |
|||
|
|||
elif len(times) > 0: |
|||
for time in times: |
|||
encounter["data"]["day"] = None |
|||
encounter["data"]["time"] = time |
|||
self.encounters.append(encounter) |
|||
|
|||
else: |
|||
encounter["data"]["day"] = None |
|||
encounter["data"]["time"] = None |
|||
self.encounters.append(encounter) |
|||
|
|||
def process_event_tables(self, events_section): |
|||
event_tables = {} |
|||
if events_section: |
|||
next_element = events_section.parent.find_next_sibling() |
|||
while next_element and next_element.name != 'h3': |
|||
if next_element.name == 'h5': |
|||
variant = next_element.text.strip() |
|||
table = next_element.find_next_sibling('table', class_='roundy') |
|||
if table: |
|||
event_tables[variant] = table |
|||
next_element = next_element.find_next_sibling() |
|||
return event_tables |
|||
|
|||
def process_event_table(self, table, game_locations): |
|||
for row in table.find_all('tr')[1:]: # Skip header row |
|||
cells = row.find_all('td') |
|||
if len(cells) >= 6: # Ensure all required columns are present |
|||
# Extract game names as a list |
|||
game_links = cells[0].find_all('a') |
|||
individual_games = [] |
|||
|
|||
for link in game_links: |
|||
# Replace specific known prefixes |
|||
game_name = link['title'].replace("Pokémon ", "").replace("Versions", "").replace(" Version", "").replace(" (Japanese)", "") |
|||
|
|||
# Split on " and ", which is used for combined games |
|||
parsed_names = game_name.split(" and ") |
|||
|
|||
# Add the parsed names to the list |
|||
individual_games.extend(parsed_names) |
|||
|
|||
# Print extracted game names for debugging |
|||
print(f"Extracted game names from row: {individual_games}") |
|||
|
|||
# Filter games to include only those in all_games |
|||
matching_games = [] |
|||
|
|||
for game in individual_games: |
|||
match = is_mainline_game(game) |
|||
if match: |
|||
matching_games.append(game) |
|||
|
|||
# Print matching games for debugging |
|||
print(f"Matching games after filtering: {matching_games}") |
|||
|
|||
if matching_games: |
|||
location = cells[2].text.strip() |
|||
distribution_period = cells[5].text.strip() |
|||
for game in matching_games: |
|||
if game not in game_locations: |
|||
game_locations[game] = [] |
|||
game_locations[game].append({ |
|||
"location": f"Event: {location}", |
|||
"tag": str(cells[2]) |
|||
}) |
|||
Loading…
Reference in new issue