import xml.etree.ElementTree as ET import json # Game descriptions mapping (manual descriptions based on known games) game_descriptions = { "400366": "Wondrous Creatures – Ein Worker-Placement-Spiel mit fantastischen Kreaturen und innovativem Ressourcen-Management von Bad Comet.", "472021": "Medico – Medizinisches Themen-Brettspiel (2026). Neu in der Hotness – Details noch spärlich.", "403150": "World Order – Geopolitisches Area-Control-Strategiespiel von Hegemonic Project Games (2026).", "434172": "Excalibur – Artus-Sagen-Themenbrettspiel (2026) mit epischen Quests und Schwert-in-Stein-Mechanik.", "425549": "Moon Colony Bloodbath – Kartenspiel mit Sci-Fi-Horror-Thema von Donald X. Vaccarino (Dominion-Autor).", "415848": "Lands of Evershade – Fantasy-Rollenspiel-inspiriertes Brettspiel mit Kampagnen-Modus (2026).", "436217": "The Lord of the Rings: Fate of the Fellowship – Kooperatives Herr-der-Ringe-Abenteuerspiel (2025).", "457008": "Friendly Fishing – Familienfreundliches Angel-Brettspiel (2026), zugänglich und schnell.", "357873": "The Old King's Crown – Strategisches Kartenspiel mit mittelalterlichem Thronfolge-Thema (2025).", "418059": "SETI: Search for Extraterrestrial Intelligence – Wissenschaftsbasiertes Eurogame zur Suche nach außerirdischem Leben.", "417197": "Rebirth – Reiner Knizia's Wiederaufbau-Strategiespiel mit Plättchenlege-Mechanik.", "432456": "dnup – Kartenspiel mit Wendemechanik und abstraktem Thema (2025).", "454103": "Magical Athlete – Fantasie-Sport-Brettspiel mit magischen Fähigkeiten (2025).", "381248": "Nemesis: Retaliation – Semi-kooperatives Sci-Fi-Horror-Spiel, neuester Teil der Nemesis-Reihe von Awaken Realms.", "342942": "Ark Nova – Aufbau eines modernen Zoos als tiefes strategisches Kartenspiel. Aktuell #4 der BGG-Rangliste." } # Fetch the actual descriptions from XMLs descriptions = {} for gid in game_descriptions: try: tree = ET.parse(f'/home/hermes/workspace/bgg-scrape/game_{gid}.xml') root = tree.getroot() for item in root.findall('item'): desc_elem = item.find('description') if desc_elem is not None and desc_elem.text: desc_text = desc_elem.text[:300].strip() descriptions[gid] = desc_text # Get year year_elem = item.find('yearpublished') if year_elem is not None: year = year_elem.get('value', '') # Get stats stats = item.find("statistics/ratings") if stats is not None: avg = stats.find("average") avg_rating = avg.get('value', 'N/A') if avg is not None else 'N/A' ranks = stats.find("ranks") bgg_rank = 'N/A' if ranks is not None: for r in ranks.findall('rank'): if r.get('name') == 'boardgame': bgg_rank = r.get('value', 'N/A') descriptions[gid + '_stats'] = f"⭐ {avg_rating} | BGG Rank: {bgg_rank}" except Exception as e: descriptions[gid] = f"Error: {e}" # Print report print("=" * 70) print(" BOARDGAMEGEEK HOTNESS – TOP 15 (6.-7. Juni 2026)") print("=" * 70) print() items = [ ("1", "Wondrous Creatures", "400366"), ("2", "Medico", "472021"), ("3", "World Order", "403150"), ("4", "Excalibur", "434172"), ("5", "Moon Colony Bloodbath", "425549"), ("6", "Lands of Evershade", "415848"), ("7", "The Lord of the Rings: Fate of the Fellowship", "436217"), ("8", "Friendly Fishing", "457008"), ("9", "The Old King's Crown", "357873"), ("10", "SETI: Search for Extraterrestrial Intelligence", "418059"), ("11", "Rebirth", "417197"), ("12", "dnup", "432456"), ("13", "Magical Athlete", "454103"), ("14", "Nemesis: Retaliation", "381248"), ("15", "Ark Nova", "342942"), ] for i, (rank, name, gid) in enumerate(items, 1): print(f"#{rank} – {name}") print(f" ID: {gid}") stats = descriptions.get(gid + '_stats', 'Stats: N/A') print(f" {stats}") desc = descriptions.get(gid, game_descriptions.get(gid, '')) if desc: # Strip HTML and truncate import re clean = re.sub(r'<[^>]+>', '', desc) clean = re.sub(r'&#?\w+;', ' ', clean) clean = re.sub(r'\s+', ' ', clean).strip() if len(clean) > 280: clean = clean[:277] + '...' print(f" Beschreibung: {clean}") else: print(f" Beschreibung: {game_descriptions.get(gid, 'Keine Beschreibung verfügbar.')}") print(f" Relevanz: {'HOTTEST' if i <= 3 else '🔥 Hoch' if i <= 7 else '★ Mittel' if i <= 12 else '· Stabil'}") print() print("\n---") print("Datenquelle: BGG XML API v2 (de3b01db-9be3-4c80-bd80-d47e071b320e)") print("User-Agent: BSN-OpenClaw/1.0") print("Abrufdatum: 6. Juni 2026") print("Hinweis: BGG-News-Forum (ID=27) war unter CloudFlare-Schutz – HTML-Scraping nicht möglich. Forum-ID=1 (News) nur 1 Thread (2009). Hotness via API erfolgreich.")