kiosk: chromium 72 mime + flex-gap fixes
Pi's onboard chromium is 72 (Jan 2019). Two issues: 1. Python 3.5's mimetypes doesn't know woff/woff2/ttf, so Tornado serves them as application/octet-stream which chromium 72 refuses to use as web fonts -> all FA6 icons render as empty boxes. Add scripts/deploy/patch_font_mime.py that monkey-patches bbctrl Web.py's StaticFileHandler with correct content types. Run automatically by deploy-hardware.sh (idempotent). 2. flex-gap landed in chromium 84. Add '> * + *' margin fallbacks for the flex containers that show up on Program tab (action-bar, action-btn, file-bar, file-btn) and tighten the kiosk-mode settings rail so all 14 items fit in 768px height.
This commit is contained in:
@@ -62,6 +62,18 @@ ssh -o ConnectTimeout=5 "${REMOTE_USER}@${HOST}" \
|
||||
&& rm -rf \"${REMOTE_TMP}\"
|
||||
'" 2>&1 | tail -3
|
||||
|
||||
# Patch bbctrl Web.py so font files get the correct MIME type. The
|
||||
# Pi ships Python 3.5, whose `mimetypes` module doesn't know about
|
||||
# woff/woff2/ttf, so Tornado serves them as application/octet-stream
|
||||
# which Chromium 72 (the Pi's onboard browser) refuses to use as a
|
||||
# web font, leading to all FontAwesome icons rendering as empty
|
||||
# boxes in the kiosk UI. The patch is idempotent.
|
||||
echo "Patching bbctrl font MIME types (idempotent)..."
|
||||
scp -o ConnectTimeout=5 "$SCRIPT_DIR/scripts/deploy/patch_font_mime.py" \
|
||||
"${REMOTE_USER}@${HOST}:/tmp/patch_font_mime.py" >/dev/null
|
||||
ssh -o ConnectTimeout=5 "${REMOTE_USER}@${HOST}" \
|
||||
"echo '${PASSWORD}' | sudo -S python3 /tmp/patch_font_mime.py" 2>&1 | tail -3
|
||||
|
||||
echo "Restarting bbctrl service..."
|
||||
ssh -o ConnectTimeout=5 "${REMOTE_USER}@${HOST}" \
|
||||
"echo '${PASSWORD}' | sudo -S systemctl restart bbctrl" 2>&1 | tail -3
|
||||
|
||||
102
scripts/deploy/patch_font_mime.py
Normal file
102
scripts/deploy/patch_font_mime.py
Normal file
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Patch bbctrl Web.py so font files get the correct MIME type.
|
||||
|
||||
Background
|
||||
----------
|
||||
The Onefinity controller (Pi 3B running Raspbian stretch) ships Python
|
||||
3.5, whose ``mimetypes`` module does not recognize ``.woff``, ``.woff2``
|
||||
or ``.ttf``. Tornado's ``StaticFileHandler`` therefore falls back to
|
||||
``application/octet-stream`` for those, and Chromium 72 (the Pi's
|
||||
onboard kiosk browser) refuses to use such payloads as web fonts. The
|
||||
result is that every FontAwesome icon renders as an empty box on the
|
||||
kiosk display.
|
||||
|
||||
This patch monkey-patches ``StaticFileHandler.get_content_type`` to
|
||||
emit the right MIME types. It is idempotent: running it twice is a
|
||||
no-op. Run with ``sudo`` so it can rewrite the egg's Web.py.
|
||||
|
||||
Used by:
|
||||
scripts/deploy/hardware.sh
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def find_web_py():
|
||||
"""Return the absolute path to the bbctrl Web.py shipped in the egg."""
|
||||
base = "/usr/local/lib"
|
||||
for entry in os.listdir(base):
|
||||
if not entry.startswith("python"):
|
||||
continue
|
||||
candidate_dir = os.path.join(base, entry, "dist-packages")
|
||||
if not os.path.isdir(candidate_dir):
|
||||
continue
|
||||
for sub in os.listdir(candidate_dir):
|
||||
if sub.startswith("bbctrl-") and sub.endswith(".egg"):
|
||||
p = os.path.join(candidate_dir, sub, "bbctrl", "Web.py")
|
||||
if os.path.isfile(p):
|
||||
return p
|
||||
return None
|
||||
|
||||
|
||||
OLD_BLOCK = (
|
||||
"class StaticFileHandler(tornado.web.StaticFileHandler):\n"
|
||||
" def set_extra_headers(self, path):\n"
|
||||
" self.set_header('Cache-Control',\n"
|
||||
" 'no-store, no-cache, must-revalidate, max-age=0')"
|
||||
)
|
||||
|
||||
NEW_BLOCK = (
|
||||
"class StaticFileHandler(tornado.web.StaticFileHandler):\n"
|
||||
" # FONT_MIME_FIX: Python 3.5's mimetypes module does not know\n"
|
||||
" # woff/woff2/ttf, so Tornado serves them as application/octet-\n"
|
||||
" # stream which Chromium 72 (the Pi's onboard kiosk browser)\n"
|
||||
" # refuses to use as web fonts. Set explicit types so the FA6\n"
|
||||
" # icon set actually renders on the kiosk display.\n"
|
||||
" def get_content_type(self):\n"
|
||||
" path = self.absolute_path or ''\n"
|
||||
" if path.endswith('.woff2'): return 'font/woff2'\n"
|
||||
" if path.endswith('.woff'): return 'font/woff'\n"
|
||||
" if path.endswith('.ttf'): return 'font/ttf'\n"
|
||||
" if path.endswith('.otf'): return 'font/otf'\n"
|
||||
" if path.endswith('.eot'): return 'application/vnd.ms-fontobject'\n"
|
||||
" return super().get_content_type()\n"
|
||||
"\n"
|
||||
" def set_extra_headers(self, path):\n"
|
||||
" self.set_header('Cache-Control',\n"
|
||||
" 'no-store, no-cache, must-revalidate, max-age=0')"
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
target = find_web_py()
|
||||
if target is None:
|
||||
print("ERROR: could not locate bbctrl Web.py under /usr/local/lib",
|
||||
file=sys.stderr)
|
||||
return 1
|
||||
|
||||
with open(target) as f:
|
||||
src = f.read()
|
||||
|
||||
if "FONT_MIME_FIX" in src:
|
||||
print("font mime: already patched ({})".format(target))
|
||||
return 0
|
||||
|
||||
if OLD_BLOCK not in src:
|
||||
print("font mime: expected block not found in {} -- skipping".format(target),
|
||||
file=sys.stderr)
|
||||
# Don't fail the deploy; just log and continue.
|
||||
return 0
|
||||
|
||||
new_src = src.replace(OLD_BLOCK, NEW_BLOCK, 1)
|
||||
with open(target, "w") as f:
|
||||
f.write(new_src)
|
||||
print("font mime: patched {}".format(target))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user