deskhop/webconfig/render.py

61 lines
1.8 KiB
Python
Raw Normal View History

#!/usr/bin/python3
# Takes a HTML file, outputs a minified and compressed version that self-decompresses when loaded.
# This way, the device config page can be fitted in a small 64 kB "flash" partition and distributed
# with the main binary.
from jinja2 import Environment, FileSystemLoader
from form import *
import base64
import zlib
# Input and output
TEMPLATE_PATH = "templates/"
INPUT_FILENAME = "main.html"
PACKER_FILENAME = "packer.j2"
OUTPUT_FILENAME = "config.htm"
OUTPUT_UNPACKED = "config-unpacked.htm"
def render(filename, *args, **kwargs):
env = Environment(loader=FileSystemLoader(TEMPLATE_PATH))
template = env.get_template(filename)
return template.render(*args, **kwargs)
def write_file(payload, filename=OUTPUT_FILENAME):
with open(filename, 'w', encoding='utf-8') as file:
file.write(payload)
def encode_file(payload):
# Compress using raw DEFLATE
compressed_data = zlib.compress(payload.encode('utf-8'))[2:-4]
# Encode to base64
base64_compressed_data = base64.b64encode(compressed_data).decode('utf-8')
return base64_compressed_data
if __name__ == "__main__":
# Read main template contents
webpage = render(
INPUT_FILENAME,
screen_A=output_A(),
screen_B=output_B(),
status=output_status(),
config=output_config(),
)
# Compress file and encode to base64
encoded_data = {'payload': encode_file(webpage)}
# Tiny Inflate JS decoder (https://github.com/foliojs/tiny-inflate)
# Decompress the data and replace existing HTML with the decoded version
self_extracting_webpage = render(PACKER_FILENAME, encoded_data)
# Write data to output filename
write_file(self_extracting_webpage)
# Write unpacked webpage
write_file(webpage, OUTPUT_UNPACKED)