91 lines
3.2 KiB
Python
91 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Search BGG for board game IDs - Batch 3"""
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
import xml.etree.ElementTree as ET
|
|
|
|
BGG_KEY = open("/tmp/.bggkey").read().strip()
|
|
HEADER = f"Authorization: Bearer {BGG_KEY}"
|
|
|
|
games = [
|
|
("1840 Age Of Lions", "1840", None),
|
|
("Cosmic Contraband", "Contraband", "Cosmic"),
|
|
("STREAM: The Game", "STREAM", None),
|
|
("Rock Hard 1977", "Rock", "Hard"),
|
|
("VEX - The Vegan Experiment", "VEX", "Vegan"),
|
|
("Arcanixia", "Arcanixia", None),
|
|
("Saloon Shootout", "Saloon", "Shootout"),
|
|
("Islands of Ikaria", "Ikaria", "Islands"),
|
|
("INSANITÀ S.p.A.", "Insanita", "INSANITÀ"),
|
|
("VALKYO Trading Card Game", "Valkyo", "VALKYO"),
|
|
("SeaBound: Open Oceans", "SeaBound", "Oceans"),
|
|
("Brand Battles TCG", "Brand", "Battles"),
|
|
("Sylvan's Curse", "Sylvan", "Curse"),
|
|
("Lithomachy", "Lithomachy", None),
|
|
]
|
|
|
|
def search_bgg(query):
|
|
url = f"https://boardgamegeek.com/xmlapi2/search?query={query}&type=boardgame"
|
|
cmd = ["curl", "-s", "-H", HEADER, url]
|
|
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
|
|
return result.stdout
|
|
|
|
def parse_results(xml_str, game_name):
|
|
"""Parse XML and find exact match. Return (id, name) or None."""
|
|
try:
|
|
root = ET.fromstring(xml_str)
|
|
items = root.findall("item")
|
|
for item in items:
|
|
item_type = item.get("type", "")
|
|
if item_type != "boardgame":
|
|
continue
|
|
item_id = item.get("id", "")
|
|
name_elem = item.find("name")
|
|
if name_elem is not None:
|
|
bgg_name = name_elem.get("value", "")
|
|
if bgg_name.lower() == game_name.lower():
|
|
return (item_id, bgg_name)
|
|
# If no exact match, return first result
|
|
for item in items:
|
|
item_type = item.get("type", "")
|
|
if item_type != "boardgame":
|
|
continue
|
|
item_id = item.get("id", "")
|
|
name_elem = item.find("name")
|
|
bgg_name = name_elem.get("value", "") if name_elem is not None else ""
|
|
return (item_id, bgg_name)
|
|
return None
|
|
except ET.ParseError as e:
|
|
print(f" XML parse error: {e}", file=sys.stderr)
|
|
return None
|
|
|
|
for game_name, primary_word, fallback_word in games:
|
|
print(f"Searching: {game_name} (query: {primary_word})", file=sys.stderr)
|
|
|
|
xml_out = search_bgg(primary_word)
|
|
result = parse_results(xml_out, game_name)
|
|
|
|
if result:
|
|
bgg_id, bgg_name = result
|
|
url = f"https://boardgamegeek.com/boardgame/{bgg_id}"
|
|
print(f"{game_name}|{bgg_id}|{url}")
|
|
elif fallback_word:
|
|
time.sleep(3)
|
|
print(f" Primary failed, trying fallback: {fallback_word}", file=sys.stderr)
|
|
xml_out = search_bgg(fallback_word)
|
|
result = parse_results(xml_out, game_name)
|
|
if result:
|
|
bgg_id, bgg_name = result
|
|
url = f"https://boardgamegeek.com/boardgame/{bgg_id}"
|
|
print(f"{game_name}|{bgg_id}|{url}")
|
|
else:
|
|
print(f"{game_name}|NOT_FOUND")
|
|
else:
|
|
print(f"{game_name}|NOT_FOUND")
|
|
|
|
sys.stdout.flush()
|
|
time.sleep(3)
|
|
|
|
print("Done!", file=sys.stderr)
|