diff --git a/README.md b/README.md index 1fa395b..ba1bfe2 100644 --- a/README.md +++ b/README.md @@ -356,9 +356,9 @@ for name, count in sorted(cards.items()): - **Unique cards:** 916 - **By type:** - Artifacts: 77 - - Creatures: 392 + - Creatures: 393 - Enchantments: 64 - - Instants: 109 + - Instants: 110 - Lands: 72 - Planeswalkers: 2 - Sorceries: 95 diff --git a/hydrate.py b/hydrate.py index 63f879d..3fefa12 100644 --- a/hydrate.py +++ b/hydrate.py @@ -40,8 +40,21 @@ def parse_decklist(filepath: str) -> list[dict]: return cards +def strip_set_code(name: str) -> str: + """Remove set code and collector number from card name. + + E.g., "Keep Out (ECL) 19" -> "Keep Out" + """ + name = re.sub(r'\s*\([^)]+\)\s*\d+ *$', '', name) + name = re.sub(r'\s*\*F\*$', '', name) + return name.strip() + + def fetch_card(name: str, retry_count: int = 3) -> Optional[dict]: """Fetch card data from Scryfall API using fuzzy search.""" + original_name = name + name = strip_set_code(name) + encoded = urllib.parse.quote(name) url = f"{SCRYFALL_API}/cards/named?fuzzy={encoded}" @@ -59,7 +72,10 @@ def fetch_card(name: str, retry_count: int = 3) -> Optional[dict]: print(f" Rate limited. Waiting {retry_after}s...", file=sys.stderr) time.sleep(retry_after) elif e.code == 404: - print(f" Error fetching '{name}': Not found", file=sys.stderr) + if name != original_name: + print(f" Not found with set code, retrying: '{name}'", file=sys.stderr) + return fetch_card(name, retry_count=1) + print(f" Error fetching '{original_name}': Not found", file=sys.stderr) return None else: if attempt < retry_count - 1: @@ -67,13 +83,13 @@ def fetch_card(name: str, retry_count: int = 3) -> Optional[dict]: print(f" HTTP {e.code}, retrying in {wait_time}s...", file=sys.stderr) time.sleep(wait_time) else: - print(f" Error fetching '{name}': HTTP {e.code}", file=sys.stderr) + print(f" Error fetching '{original_name}': HTTP {e.code}", file=sys.stderr) return None except urllib.error.URLError as e: - print(f" Error fetching '{name}': {e.reason}", file=sys.stderr) + print(f" Error fetching '{original_name}': {e.reason}", file=sys.stderr) return None except json.JSONDecodeError: - print(f" Error parsing response for '{name}'", file=sys.stderr) + print(f" Error parsing response for '{original_name}'", file=sys.stderr) return None return None