Files
felhom-controller/controller/scripts/emoji_gate.py
T
admin 622d9328f8 D1 Part 3 leftovers: remove 8 residual emoji + Python emoji gate
- The D0 grep gate false-negatived multibyte emoji on Windows (its zero
  was wrong). scripts/emoji_gate.py scans by Unicode codepoint; it found
  8 survivors: backups.html (📁→file-text icon, 🔄 restore-info text),
  debug.html (🔄→'fut', 🔒→'titkosított'), deploy.html (📦→upload icon,
  ★ default-marker → '(alapértelmezett)'), storage.html (📦→upload icon,
  📦 in the migrate-target option → plain text). All → sprite icons or
  plain words.
- Gates: scripts/emoji_gate.py = 0; new Go TestNoEmojiInTemplates
  codepoint scan keeps it enforced (allowlist: ✓✗✔✘•●○■▶ monochrome
  text marks). go build/vet/test ./... green (18 pkgs).
2026-07-02 19:19:23 +02:00

70 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""D1 §10 Python emoji gate — Windows grep silently fails to match multibyte emoji (the D0
grep-gate zero was a false negative). This scans templates by Unicode codepoint.
Run from controller/: python scripts/emoji_gate.py
Exit 1 if any emoji/pictograph remains in web+setup templates.
"""
import io, os, sys, unicodedata
ROOTS = [
os.path.join("internal", "web", "templates"),
os.path.join("internal", "setup", "templates"),
]
# Codepoint ranges that count as "emoji / pictographs / dingbats" for UI-copy purposes.
# Deliberately does NOT flag Hungarian letters, typographic quotes/dashes, the middle dot (·),
# arrows used as affordances (→ ↗ ↻ ↑ ↓), the multiplication sign (×), or box-drawing.
def is_emoji(ch):
o = ord(ch)
ranges = [
(0x1F300, 0x1FAFF), # Misc symbols & pictographs, emoticons, transport, supplemental, symbols-ext
(0x2600, 0x26FF), # Misc symbols (☀ ⚙ ⚠ ☁ …)
(0x2700, 0x27BF), # Dingbats (✅ ✂ ✈ ✏ ✓? no — see allow)
(0x1F000, 0x1F0FF), # Mahjong/dominoes/cards
(0xFE00, 0xFE0F), # Variation selectors (emoji presentation)
(0x1F1E6, 0x1F1FF), # Regional indicators
]
if any(a <= o <= b for a, b in ranges):
return True
return False
# Dingbat codepoints that are legitimate UI glyphs (checkmarks/crosses used as plain text marks,
# not emoji). We keep these OUT of the ban — they render as monochrome text, not color emoji.
ALLOW = set("✓✗✔✘•●○■▶") # ✓ ✗ ✔ ✘ • ● ○ ■ ▶
def scan(path):
hits = []
for lineno, line in enumerate(io.open(path, encoding="utf-8"), 1):
for ch in line:
if ch in ALLOW:
continue
if is_emoji(ch):
try:
name = unicodedata.name(ch)
except ValueError:
name = "U+%04X" % ord(ch)
hits.append((lineno, ch, name))
return hits
def main():
total = 0
for root in ROOTS:
for fn in sorted(os.listdir(root)):
if not fn.endswith(".html"):
continue
path = os.path.join(root, fn)
for lineno, ch, name in scan(path):
total += 1
print("%s:%d %s %s" % (fn, lineno, ch, name))
if total:
print("EMOJI GATE FAILED: %d emoji found" % total)
sys.exit(1)
print("emoji gate OK — no emoji in web/setup templates")
if __name__ == "__main__":
main()