add game tracker with owned pokemon data and call of duty mastery
All checks were successful
Test and deploy staging / staging (push) Successful in 18s
All checks were successful
Test and deploy staging / staging (push) Successful in 18s
Fold catchemall into /projects/game-tracker (old URL redirects) and add Call of Duty tracking for Black Ops through WWII. - Pokémon catalog is now owned: locations, encounters and per-game evolution methods are built from the pinned PokéAPI snapshot and seeded. - Pokémon you can evolve or breed in a game count as obtainable; mythicals without another route are marked event-only. - Detail dialog with evolution chain and where to find it, location pages with admin notes and pictures, and admin corrections that survive reseeds. - Call of Duty weapons, milestones and Steam achievements per game, with derived Diamond / Dark Matter / Solar / Black Sky / Chrome tiers. - New migration (db:migrate:game-tracker), seeds (db:seed, db:seed:cod) and deploy preflight checks for them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
49
scripts/build-cod-catalog.py
Normal file
49
scripts/build-cod-catalog.py
Normal file
@@ -0,0 +1,49 @@
|
||||
"""Refresh the achievement lists in data/call-of-duty.json from Steam Community.
|
||||
|
||||
Weapons, classes and mastery rules in that file are hand-maintained; this only
|
||||
replaces each game's `achievements` array with the public global achievement
|
||||
pages of its Steam apps. Keys are `<app id>:<slug>` so progress survives renames
|
||||
of descriptions or icons.
|
||||
"""
|
||||
import html
|
||||
import json
|
||||
from pathlib import Path
|
||||
import re
|
||||
import urllib.request
|
||||
|
||||
TARGET = Path(__file__).resolve().parent.parent / 'data/call-of-duty.json'
|
||||
ROW = re.compile(r'<div class="achieveRow.*?<img src="([^"]+)".*?<h3>(.*?)</h3>\s*<h5>(.*?)</h5>', re.S)
|
||||
|
||||
|
||||
def slug(text):
|
||||
return re.sub(r'[^a-z0-9]+', '-', text.lower()).strip('-')
|
||||
|
||||
|
||||
def achievements(app):
|
||||
request = urllib.request.Request(f"https://steamcommunity.com/stats/{app['id']}/achievements/?l=english",
|
||||
headers={'User-Agent': 'stanrunge.dev game-tracker catalog builder'})
|
||||
with urllib.request.urlopen(request, timeout=60) as response:
|
||||
page = response.read().decode('utf-8')
|
||||
rows, seen = [], {}
|
||||
for icon, name, description in ROW.findall(page):
|
||||
name, description = html.unescape(name).strip(), html.unescape(description).strip()
|
||||
key = f"{app['id']}:{slug(name)}"
|
||||
seen[key] = seen.get(key, 0) + 1
|
||||
if seen[key] > 1:
|
||||
key += f'-{seen[key]}'
|
||||
rows.append(dict(key=key, category=app['label'], name=name, description=description or None, icon=icon))
|
||||
if not rows:
|
||||
raise RuntimeError(f"No achievements parsed for Steam app {app['id']}")
|
||||
return rows
|
||||
|
||||
|
||||
def main():
|
||||
catalog = json.loads(TARGET.read_text())
|
||||
for game in catalog['games']:
|
||||
game['achievements'] = [row for app in game['steamApps'] for row in achievements(app)]
|
||||
print(f"{game['shortName']}: {len(game['achievements'])} achievements")
|
||||
TARGET.write_text(json.dumps(catalog, ensure_ascii=False, indent='\t') + '\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user