#!/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}}
{{defindex}} |
{{name}} |
{{item_name}} |
{{item_slot}} |
{{item_class}} |
{{/result.items}}
{{#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
}))