Add PokeDB sprite downloading (100x100 WebP)

Download pokemon sprites from PokeDB CDN during import, cached locally
as {pokeapi_id}.webp. Replaces PokeAPI GitHub sprite URLs. ~4.6MB for
all 1119 unique sprites.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Julian Tabel
2026-02-11 10:24:43 +01:00
parent d80c59047c
commit 29b954726a
4 changed files with 105 additions and 4 deletions

View File

@@ -0,0 +1,78 @@
"""Download and manage PokeDB pokemon sprites."""
from __future__ import annotations
import sys
import urllib.request
from pathlib import Path
from typing import Any
from .mappings import PokemonMapper
def download_sprites(
pokemon_mapper: PokemonMapper,
encountered_form_ids: set[str],
sprites_dir: Path,
) -> dict[str, str]:
"""Download sprites for all encountered pokemon forms.
Returns a mapping of pokemon_form_identifier → local sprite filename.
Skips already-downloaded sprites.
"""
sprites_dir.mkdir(parents=True, exist_ok=True)
to_download: list[tuple[str, str, Path]] = [] # (form_id, url, dest)
result: dict[str, str] = {}
for form_id in sorted(encountered_form_ids):
info = pokemon_mapper.lookup(form_id)
if info is None:
continue
pokeapi_id, _ = info
sprite_url = pokemon_mapper.get_sprite_url(form_id)
if not sprite_url:
continue
filename = f"{pokeapi_id}.webp"
dest = sprites_dir / filename
result[form_id] = filename
if not dest.exists():
to_download.append((form_id, sprite_url, dest))
if not to_download:
print(f" Sprites: {len(result)} already cached")
return result
print(f" Downloading {len(to_download)} sprites ({len(result) - len(to_download)} cached)...")
failed = 0
for i, (form_id, url, dest) in enumerate(to_download, 1):
try:
urllib.request.urlretrieve(url, dest)
except Exception as e:
print(f" Warning: Failed to download sprite for {form_id}: {e}", file=sys.stderr)
failed += 1
# Remove the failed entry from results
result.pop(form_id, None)
# Progress every 100
if i % 100 == 0:
print(f" {i}/{len(to_download)}...")
if failed:
print(f" Sprites: {len(result)} downloaded, {failed} failed")
else:
print(f" Sprites: {len(result)} total ({len(to_download)} new)")
return result
def sprite_path_for_pokemon(pokeapi_id: int, sprites_dir_name: str = "sprites") -> str:
"""Generate the relative sprite path for use in pokemon.json.
Returns a path like "sprites/25.webp" suitable for the sprite_url field.
"""
return f"{sprites_dir_name}/{pokeapi_id}.webp"