#!/usr/bin/python3 import base64 import chevron import configparser import datetime import hashlib import html.parser import io import json import urllib import urllib.request import urllib.parse template_string = r''' TF2 Item List

List of Team Fortress 2 items:

Page generated for schema last modified {{update_time}}. Click here to download this page for offline viewing.

{{#result.items}} {{/result.items}}
ID Internal Name Localized Name Item Slot Entity
{{defindex}} {{name}} {{item_name}} {{item_slot}} {{item_class}}
{{#inline_scripts}} {{/inline_scripts}} ''' def process_item_class(item): used_by = item.get("used_by_classes", []) if used_by: item['used_by_classes'] = [ { "class": c.lower() } for c in used_by ] return item def get_schema_items(params): opts = dict(params.items()) opts['start'] = 0 url = "https://api.steampowered.com/IEconItems_440/GetSchemaItems/v0001/" while True: with urllib.request.urlopen(f"{url}?{urllib.parse.urlencode(opts)}") as r: data = json.load(r)['result'] yield from data.get('items', []) if 'next' not in data: break opts['start'] = data['next'] def inline_scripts(text, render): """ Helper function to parse script elements, download the scripts and inline them. """ class ScriptElementParser(html.parser.HTMLParser): def __init__(self): super(ScriptElementParser, self).__init__() self.scripts = [] self.current = [] def handle_starttag(self, tag, attrs): if tag == 'script': self.current.append(dict(attrs)) def handle_endtag(self, tag): self.scripts.append(self.current.pop()) parser = ScriptElementParser() parser.feed(text) f = io.StringIO() for script in parser.scripts: with urllib.request.urlopen(script['src']) as r: data = r.read() if 'integrity' in script: ct, hash = script['integrity'].split('-', 1) h = hashlib.new(ct) h.update(data) if base64.b64encode(h.digest()).decode('ascii') != hash: raise ValueError(f"{script['src']} failed subresource integrity check {script['integrity']} (got {base64.b64encode(h.digest())})") f.write(f"\n") return f.getvalue() def schema_mtime(params): url = "https://api.steampowered.com/IEconItems_440/GetSchemaOverview/v0001/" with urllib.request.urlopen(f"{url}?{urllib.parse.urlencode(dict(params.items()))}") as r: return r.info().get('last-modified') config = configparser.ConfigParser() config.read('config.ini', encoding = "utf8") with open('items.html', 'wt', encoding = 'utf8') as f: f.write(chevron.render(template_string, { 'result': { 'items': list(map(process_item_class, get_schema_items(config['DEFAULT']))) }, 'update_time': schema_mtime(config['DEFAULT']), 'inline_scripts': inline_scripts }))