#!/usr/bin/env python3 import subprocess, sys, time, xml.etree.ElementTree as ET KEY = open("/tmp/.bggkey").read().strip() HEADER = "Authorization: Bearer " + KEY BASE = "https://boardgamegeek.com/xmlapi2/search?query={}&type=boardgame" GAMES = [ ("Dark Kingdoms", "Kingdoms", None), ("The 30s", "30s", None), ("Age of Comics: The Vault Collection", "Comics", "Vault"), ("Orbital", "Orbital", None), ("Zerca", "Zerca", None), ("Menu del dia", "Menu", "dia"), ("Kangouroute", "Kangouroute", None), ("Dribble 'n' Dice", "Dribble", "Dice"), ("Hideouts: Legends of The Forest", "Hideouts", "Legends"), ("Elora: Tales of the Realm", "Elora", "Tales"), ("Rules of Sacred Realm", "Sacred", "Realm"), ("Project: New Earth", "Project", "Earth"), ("Vermines", "Vermines", None), ("Vatrakill", "Vatrakill", None), ] def search(word): url = BASE.format(word) cmd = ["curl", "-s", "-H", HEADER, url] r = subprocess.run(cmd, capture_output=True, text=True, timeout=30) return r.stdout def parse_first_match(xml_text, target_name): try: root = ET.fromstring(xml_text) except ET.ParseError: return None target_lower = target_name.strip().lower() for item in root.findall("item"): for name_el in item.findall("name"): if name_el.get("type") == "primary": val = (name_el.get("value") or "").strip().lower() if val == target_lower: return (item.get("id"), name_el.get("value")) return None def find_any_match(xml_text): try: root = ET.fromstring(xml_text) except ET.ParseError: return None for item in root.findall("item"): for name_el in item.findall("name"): if name_el.get("type") == "primary": return (item.get("id"), name_el.get("value")) return None results = [] for game_name, word1, word2 in GAMES: print("Searching: {} (word: {})".format(game_name, word1), file=sys.stderr) xml1 = search(word1) match = parse_first_match(xml1, game_name) if match: bgg_id, bgg_name = match url = "https://boardgamegeek.com/boardgame/{}".format(bgg_id) results.append("{}|{}|{}".format(game_name, bgg_id, url)) print(" -> EXACT MATCH: {} (id={})".format(bgg_name, bgg_id), file=sys.stderr) elif word2: time.sleep(3) print(" No exact match. Trying fallback: {}".format(word2), file=sys.stderr) xml2 = search(word2) match = parse_first_match(xml2, game_name) if match: bgg_id, bgg_name = match url = "https://boardgamegeek.com/boardgame/{}".format(bgg_id) results.append("{}|{}|{}".format(game_name, bgg_id, url)) print(" -> EXACT MATCH (fallback): {} (id={})".format(bgg_name, bgg_id), file=sys.stderr) else: any_match = find_any_match(xml2) if any_match: bgg_id, bgg_name = any_match url = "https://boardgamegeek.com/boardgame/{}".format(bgg_id) results.append("{}|{}|{}".format(game_name, bgg_id, url)) print(" -> FALLBACK ANY MATCH: {} (id={})".format(bgg_name, bgg_id), file=sys.stderr) else: results.append("{}|NOT_FOUND".format(game_name)) print(" -> NOT_FOUND", file=sys.stderr) else: any_match = find_any_match(xml1) if any_match: bgg_id, bgg_name = any_match url = "https://boardgamegeek.com/boardgame/{}".format(bgg_id) results.append("{}|{}|{}".format(game_name, bgg_id, url)) print(" -> ANY MATCH: {} (id={})".format(bgg_name, bgg_id), file=sys.stderr) else: results.append("{}|NOT_FOUND".format(game_name)) print(" -> NOT_FOUND", file=sys.stderr) time.sleep(3) print() print("=== RESULTS ===") for line in results: print(line)