Add build.py: bundles all assets into a single standalone HTML
This commit is contained in:
1 parent
3ccc3e4be7
commit
8e05444cfb
2 files changed
+2610
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,94 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Build a single self-contained HTML file from the source files.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python3 build.py [output.html]
|
||||||
|
|
||||||
|
If output is not given, defaults to 'background-final.html'.
|
||||||
|
|
||||||
|
This reads config.js to pick the active theme and inlines all CSS,
|
||||||
|
JS, and the noise.png texture into a single HTML document. After
|
||||||
|
building, the resulting double-standalone HTML can be opened directly in
|
||||||
|
a browser (file://) because all external resources are inlined.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import base64
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
ROOT = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
|
||||||
|
def read(path):
|
||||||
|
with open(os.path.join(ROOT, path), 'r', encoding='utf-8') as f:
|
||||||
|
return f.read()
|
||||||
|
|
||||||
|
|
||||||
|
def parse_config():
|
||||||
|
"""Extract window.CONFIG values from config.js."""
|
||||||
|
src = read('config.js')
|
||||||
|
out = {}
|
||||||
|
for key in ['debug', 'theme', 'units', 'language', 'timeFormat']:
|
||||||
|
m = re.search(r"\b%s\s*:\s*'([^']*)'" % key, src) or re.search(r'\b%s\s*:\s*(\d+)' % key, src)
|
||||||
|
if m:
|
||||||
|
out[key] = m.group(1)
|
||||||
|
m = re.search(r'lat\s*:\s*([\d.]+)', src)
|
||||||
|
if m:
|
||||||
|
out['lat'] = m.group(1)
|
||||||
|
m = re.search(r'lon\s*:\s*([-\d.]+)', src)
|
||||||
|
if m:
|
||||||
|
out['lon'] = m.group(1)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
out = sys.argv[1] if len(sys.argv) > 1 else 'background-final.html'
|
||||||
|
|
||||||
|
cfg = parse_config()
|
||||||
|
theme = cfg.get('theme', 'ash')
|
||||||
|
|
||||||
|
html = read('background.html')
|
||||||
|
|
||||||
|
# Resolve active theme css
|
||||||
|
theme_css = read(theme + '.css')
|
||||||
|
# Inline the active theme stylesheet at the end of <head>
|
||||||
|
html = html.replace('</head>',
|
||||||
|
'<style>\n' + theme_css + '\n</style>\n</head>',
|
||||||
|
1)
|
||||||
|
|
||||||
|
# Inline vendor scripts in the body, before the main script block
|
||||||
|
for _, path in [
|
||||||
|
('three', 'vendor/three.min.js'),
|
||||||
|
('suncalc', 'vendor/suncalc.js'),
|
||||||
|
('vanta2', 'vendor/vanta.clouds2.min.js'),
|
||||||
|
('i18n', 'i18n.js'),
|
||||||
|
('config', 'config.js'),
|
||||||
|
]:
|
||||||
|
body = read(path)
|
||||||
|
html = html.replace('<script src="' + path + '"></script>',
|
||||||
|
'<script>\n' + body + '\n</script>',
|
||||||
|
1)
|
||||||
|
|
||||||
|
# Inline noise.png as data URI in the Vanta init script.
|
||||||
|
with open(os.path.join(ROOT, 'noise.png'), 'rb') as f:
|
||||||
|
noise_b64 = base64.b64encode(f.read()).decode('ascii')
|
||||||
|
noise_uri = 'data:image/png;base64,' + noise_b64
|
||||||
|
html = re.sub(
|
||||||
|
r"texturePath:\s*'[^']*'",
|
||||||
|
"texturePath: '" + noise_uri + "'",
|
||||||
|
html)
|
||||||
|
|
||||||
|
with open(os.path.join(ROOT, out), 'w', encoding='utf-8') as f:
|
||||||
|
f.write(html)
|
||||||
|
|
||||||
|
print('Wrote ' + out + ' (' + str(len(html)) + ' bytes)')
|
||||||
|
print('Config used:')
|
||||||
|
for k in ('debug', 'theme', 'units', 'language', 'timeFormat', 'lat', 'lon'):
|
||||||
|
if k in cfg:
|
||||||
|
print(' ' + k + ' = ' + cfg[k])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Reference in new issue
Block a user