|
|
|
@ -1,3 +1,4 @@ |
|
|
|
from __future__ import annotations |
|
|
|
import csv |
|
|
|
import requests |
|
|
|
import time |
|
|
|
@ -9,6 +10,7 @@ from bs4 import BeautifulSoup, Tag, NavigableString |
|
|
|
import copy |
|
|
|
from typing import List, Optional |
|
|
|
|
|
|
|
|
|
|
|
# Initialize the database connection |
|
|
|
conn = sqlite3.connect('pokemon_cache.db') |
|
|
|
cursor = conn.cursor() |
|
|
|
@ -38,6 +40,8 @@ all_games = [ |
|
|
|
"Unknown" |
|
|
|
] |
|
|
|
|
|
|
|
big_pokemon_list = [] |
|
|
|
|
|
|
|
cache = {} |
|
|
|
new_entries_count = 0 |
|
|
|
|
|
|
|
@ -65,6 +69,73 @@ def update_cache(key, value): |
|
|
|
save_cached_data() |
|
|
|
time.sleep(1) |
|
|
|
|
|
|
|
class Pokemon: |
|
|
|
def __init__(self, name: str, number: int, form: Optional[str] = None): |
|
|
|
self.name = name |
|
|
|
self.number = number |
|
|
|
self.form = form |
|
|
|
self.stage: Optional[str] = None |
|
|
|
self.evolution_chain: Optional[List['EvolutionStage']] = [] |
|
|
|
self.is_baby = False |
|
|
|
self.encounter_information: Optional[List['EncounterInformation']] = [] |
|
|
|
self.earliest_game: Optional['EncounterInformation'] = None |
|
|
|
|
|
|
|
def __str__(self): |
|
|
|
return f"{self.name} {self.form if self.form else ''} (#{self.number})" |
|
|
|
|
|
|
|
def add_evolution_chain(self, evolution_chain: List['EvolutionStage']): |
|
|
|
self.evolution_chain = evolution_chain |
|
|
|
|
|
|
|
def add_stage(self, stage: str): |
|
|
|
self.stage = stage |
|
|
|
self.is_baby = self.stage is not None and 'Baby' in self.stage |
|
|
|
|
|
|
|
def update_encounter_information(self): |
|
|
|
if not self.encounter_information: |
|
|
|
return |
|
|
|
|
|
|
|
non_catchable_methods = ["trade", "event", "global link", "poké transfer", "time capsule", "unobtainable", "pokémon home"] |
|
|
|
|
|
|
|
for encounter in self.encounter_information: |
|
|
|
for location in encounter.locations: |
|
|
|
encounter.method = "Catchable" |
|
|
|
|
|
|
|
for non_catchable in non_catchable_methods: |
|
|
|
if non_catchable in location.lower(): |
|
|
|
encounter.method = None |
|
|
|
break |
|
|
|
|
|
|
|
if encounter.method is None: |
|
|
|
continue |
|
|
|
|
|
|
|
if "first partner" in location.lower(): |
|
|
|
encounter.method = "Starter" |
|
|
|
elif "received" in location.lower(): |
|
|
|
encounter.method = "Gift" |
|
|
|
elif "evolve" in location.lower(): |
|
|
|
encounter.method = "Evolve" |
|
|
|
else: |
|
|
|
encounter.method = "Catchable" |
|
|
|
|
|
|
|
def determine_earliest_game(self): |
|
|
|
if not self.encounter_information: |
|
|
|
self.earliest_game = None |
|
|
|
return |
|
|
|
|
|
|
|
self.update_encounter_information() |
|
|
|
|
|
|
|
game_methods = {} |
|
|
|
for encounter in self.encounter_information: |
|
|
|
if encounter.method: |
|
|
|
game_methods[encounter.game.lower()] = encounter |
|
|
|
|
|
|
|
for game in all_games: |
|
|
|
if game.lower() in game_methods: |
|
|
|
self.earliest_game = game_methods[game.lower()] |
|
|
|
return |
|
|
|
|
|
|
|
self.earliest_game = None |
|
|
|
|
|
|
|
class EvolutionStage: |
|
|
|
def __init__(self, pokemon: str, method: Optional[str] = None, stage: Optional[str] = None, form: Optional[str] = None): |
|
|
|
self.pokemon = pokemon |
|
|
|
@ -78,6 +149,12 @@ class EvolutionStage: |
|
|
|
def __str__(self): |
|
|
|
return f"{self.pokemon} {self.form if self.form else ''} ({self.method if self.method else 'Base'})" |
|
|
|
|
|
|
|
class EncounterInformation: |
|
|
|
def __init__(self, game: str, locations: List[str]): |
|
|
|
self.game = game |
|
|
|
self.method = "Unknown" |
|
|
|
self.locations = locations |
|
|
|
|
|
|
|
def parse_evolution_chain(table: Tag, form: Optional[str] = None) -> List[EvolutionStage]: |
|
|
|
main_chain = [] |
|
|
|
current_stage = None |
|
|
|
@ -167,6 +244,9 @@ def read_pokemon_list(filename, limit=50): |
|
|
|
row['base_name'] = base_name.strip() |
|
|
|
row['form'] = form.strip('() ') if form else None |
|
|
|
pokemon_list.append(row) |
|
|
|
|
|
|
|
new_pokemon = Pokemon(row['base_name'], row['number'], row['form']) |
|
|
|
big_pokemon_list.append(new_pokemon) |
|
|
|
return pokemon_list |
|
|
|
|
|
|
|
def sanitize_name_and_form(name, form): |
|
|
|
@ -560,6 +640,15 @@ def get_earliest_game(encounter_data, pokemon_name, form): |
|
|
|
return "Unknown", "Unknown" |
|
|
|
|
|
|
|
def determine_earliest_games(pokemon_list, cache): |
|
|
|
for pokemon in big_pokemon_list: |
|
|
|
print(f"Processing {pokemon}") |
|
|
|
encounter_data = get_locations_from_bulbapedia(pokemon.name, pokemon.form, cache) |
|
|
|
for encounter in encounter_data: |
|
|
|
encounter_information = EncounterInformation(encounter, encounter_data[encounter]) |
|
|
|
pokemon.encounter_information.append(encounter_information) |
|
|
|
pokemon.determine_earliest_game() |
|
|
|
print(f"Processed {pokemon}: {pokemon.earliest_game.game} ({pokemon.earliest_game.method})") |
|
|
|
|
|
|
|
for pokemon in pokemon_list: |
|
|
|
print(f"Processing {pokemon['name']} (#{pokemon['number']})") |
|
|
|
encounter_data = get_locations_from_bulbapedia(pokemon['base_name'], pokemon['form'], cache) |
|
|
|
|