mirror of
https://github.com/BruceDevices/firmware.git
synced 2026-03-13 10:12:21 +08:00
203 lines
6.4 KiB
Python
203 lines
6.4 KiB
Python
import hashlib
|
|
from typing import TYPE_CHECKING, Any
|
|
import requests
|
|
|
|
if TYPE_CHECKING:
|
|
Import: Any = None
|
|
env: Any = {}
|
|
|
|
import glob
|
|
import gzip
|
|
from os import makedirs, remove, rename
|
|
from os.path import basename, dirname, exists, isfile, join
|
|
|
|
Import("env") # type: ignore
|
|
|
|
FRAMEWORK_DIR = env.PioPlatform().get_package_dir("framework-arduinoespressif32-libs")
|
|
board_mcu = env.BoardConfig()
|
|
mcu = board_mcu.get("build.mcu", "")
|
|
patchflag_path = join(FRAMEWORK_DIR,mcu, "lib", ".patched")
|
|
|
|
# patch file only if we didn't do it befored
|
|
if not isfile(join(FRAMEWORK_DIR,mcu, "lib", ".patched")):
|
|
original_file = join(FRAMEWORK_DIR,mcu, "lib", "libnet80211.a")
|
|
patched_file = join(
|
|
FRAMEWORK_DIR, mcu, "lib", "libnet80211.a.patched"
|
|
)
|
|
|
|
if mcu=="esp32c5" or mcu=="esp32c6" :
|
|
env.Execute(
|
|
"pio pkg exec -p toolchain-riscv32-esp -- riscv32-esp-elf-objcopy --weaken-symbol=ieee80211_raw_frame_sanity_check %s %s"
|
|
% (original_file, patched_file)
|
|
)
|
|
elif mcu=="esp32p4":
|
|
"""Do nothing"""
|
|
else:
|
|
env.Execute(
|
|
"pio pkg exec -p toolchain-xtensa-%s -- xtensa-%s-elf-objcopy --weaken-symbol=ieee80211_raw_frame_sanity_check %s %s"
|
|
% (mcu, mcu, original_file, patched_file)
|
|
)
|
|
|
|
if isfile("%s.old" % (original_file)):
|
|
remove("%s.old" % (original_file))
|
|
|
|
if isfile(original_file):
|
|
rename(original_file, "%s.old" % (original_file))
|
|
else:
|
|
print("Patch: Original file not found")
|
|
|
|
if isfile(patched_file):
|
|
rename(patched_file, original_file)
|
|
else:
|
|
print("Patch: Patched file not found")
|
|
|
|
|
|
def _touch(path):
|
|
with open(path, "w") as fp:
|
|
fp.write("")
|
|
|
|
env.Execute(lambda *args, **kwargs: _touch(patchflag_path))
|
|
|
|
|
|
def hash_file(file_path):
|
|
"""Generate SHA-256 hash for a single file."""
|
|
hasher = hashlib.sha256()
|
|
with open(file_path, "rb") as f:
|
|
# Read the file in chunks to avoid memory issues
|
|
for chunk in iter(lambda: f.read(4096), b""):
|
|
hasher.update(chunk)
|
|
return hasher.hexdigest()
|
|
|
|
|
|
def hash_files(file_paths):
|
|
"""Generate a combined hash for multiple files."""
|
|
combined_hash = hashlib.sha256()
|
|
|
|
for file_path in file_paths:
|
|
file_hash = hash_file(file_path)
|
|
combined_hash.update(file_hash.encode("utf-8")) # Update with the file's hash
|
|
|
|
return combined_hash.hexdigest()
|
|
|
|
|
|
def save_checksum_file(hash_value, output_file):
|
|
"""Save the hash value to a specified output file."""
|
|
with open(output_file, "w") as f:
|
|
f.write(hash_value)
|
|
|
|
|
|
def load_checksum_file(input_file):
|
|
"""Load the hash value from a specified input file."""
|
|
with open(input_file, "r") as f:
|
|
return f.readline().strip()
|
|
|
|
|
|
def minify_css(c):
|
|
minify_req = requests.post(
|
|
"https://www.toptal.com/developers/cssminifier/api/raw",
|
|
{"input": c.read().decode('utf-8')},
|
|
)
|
|
return c if minify_req is False else minify_req.text.encode('utf-8')
|
|
|
|
|
|
def minify_js(js):
|
|
minify_req = requests.post(
|
|
'https://www.toptal.com/developers/javascript-minifier/api/raw',
|
|
{'input': js.read().decode('utf-8')},
|
|
)
|
|
return js if minify_req is False else minify_req.text.encode('utf-8')
|
|
|
|
|
|
def minify_html(html):
|
|
minify_req = requests.post(
|
|
'https://www.toptal.com/developers/html-minifier/api/raw',
|
|
{'input': html.read().decode('utf-8')},
|
|
)
|
|
return html if minify_req is False else minify_req.text.encode('utf-8')
|
|
|
|
|
|
# gzip web files
|
|
def prepare_www_files():
|
|
HEADER_FILE = join(env.get("PROJECT_DIR"), "include", "webFiles.h")
|
|
filetypes_to_gzip = ["html", "css", "js"]
|
|
data_src_dir = join(env.get("PROJECT_DIR"), "embedded_resources/web_interface")
|
|
checksum_file = join(data_src_dir, "checksum.sha256")
|
|
checksum = ""
|
|
|
|
if not exists(data_src_dir):
|
|
print(f'Error: Source directory "{data_src_dir}" does not exist!')
|
|
return
|
|
|
|
if exists(checksum_file):
|
|
checksum = load_checksum_file(checksum_file)
|
|
|
|
files_to_gzip = []
|
|
for extension in filetypes_to_gzip:
|
|
files_to_gzip.extend(glob.glob(join(data_src_dir, "*." + extension)))
|
|
|
|
files_checksum = hash_files(files_to_gzip)
|
|
if files_checksum == checksum:
|
|
print("[GZIP & EMBED INTO HEADER] - Nothing to process.")
|
|
return
|
|
|
|
print(f"[GZIP & EMBED INTO HEADER] - Processing {len(files_to_gzip)} files.")
|
|
|
|
makedirs(dirname(HEADER_FILE), exist_ok=True)
|
|
|
|
with open(HEADER_FILE, "w") as header:
|
|
header.write(
|
|
"#ifndef WEB_FILES_H\n#define WEB_FILES_H\n\n#include <Arduino.h>\n\n"
|
|
)
|
|
header.write(
|
|
"// THIS FILE IS AUTOGENERATED DO NOT MODIFY IT. MODIFY FILES IN /embedded_resources/web_interface\n\n"
|
|
)
|
|
|
|
for file in files_to_gzip:
|
|
gz_file = file + ".gz"
|
|
with open(file, "rb") as src, gzip.open(gz_file, "wb") as dst:
|
|
ext = basename(file).rsplit(".", 1)[-1].lower()
|
|
if ext == 'html':
|
|
minified = minify_html(src)
|
|
elif ext == 'css':
|
|
minified = minify_css(src)
|
|
elif ext == 'js':
|
|
minified = minify_js(src)
|
|
else:
|
|
raise ValueError(f"Unsupported file type: {ext}")
|
|
|
|
# # Output minified file
|
|
# min_file = file + ".min"
|
|
# with open(min_file, "wb") as minf:
|
|
# minf.write(minified)
|
|
|
|
dst.write(minified)
|
|
|
|
with open(gz_file, "rb") as gz:
|
|
compressed_data = gz.read()
|
|
var_name = basename(file).replace(".", "_")
|
|
|
|
header.write(f"const uint8_t {var_name}[] PROGMEM = {{\n")
|
|
|
|
# Write hex values, inserting a newline every 15 bytes
|
|
for i in range(0, len(compressed_data), 15):
|
|
hex_chunk = ", ".join(
|
|
f"0x{byte:02X}" for byte in compressed_data[i : i + 15]
|
|
)
|
|
header.write(f" {hex_chunk},\n")
|
|
|
|
header.write("};\n\n")
|
|
header.write(
|
|
f"const uint32_t {var_name}_size = {len(compressed_data)};\n\n"
|
|
)
|
|
|
|
remove(gz_file) # Clean up temporary gzip file
|
|
|
|
header.write("#endif // WEB_FILES_H\n")
|
|
|
|
save_checksum_file(files_checksum, checksum_file)
|
|
|
|
print(f"[DONE] Gzipped files embedded into {HEADER_FILE}")
|
|
|
|
|
|
prepare_www_files()
|