# -*- coding: utf-8 -*-
"""新前端页面装配 —— shell.html + app.css + app.js + 语言包, 按语言出一页。
出页面之前先跑 lang.check(): 英文缺条目 / 含中文 / 占位符不一致 = **这里就 FAIL**,
不会走到用户眼前变成一处中文残留。这是新旧架构最根本的差别。
"""
from __future__ import annotations
import json
import pathlib
from .. import lang
_HERE = pathlib.Path(__file__).resolve().parent # pages/
_ASSETS = _HERE.parent / 'assets' # 前端资源件 (js/css)
def _read(name: str) -> str:
"""资源件在 assets/,页面外壳在 pages/ —— 两处都找(P5 分目录后)。"""
for d in (_HERE, _ASSETS):
f = d / name
if f.is_file():
return f.read_text(encoding='utf-8')
raise FileNotFoundError(f'前端资源件缺失: {name}(pages/ 与 assets/ 都没有)')
def render(which: str = 'zh', include_records=True) -> str:
if which not in lang.LANGS:
raise ValueError('未知语言 %r' % which)
bad = lang.check()
if bad:
raise RuntimeError('语言包未过闸, 拒绝出页:\n ' + '\n '.join(bad))
pack = lang.pack(which)
if which == 'zh':
# 显示层术语映射 (app_frontEnd/configs/terms/display_map.yaml): 界面标签在这里过一遍;
# 数据里的内部词由前端 displayText 用 __display_zh 同表处理 (数据与匹配逻辑一律不动)。
from ..terms import humanize, pairs
pack = {k: (humanize(v) if isinstance(v, str) else v) for k, v in pack.items()}
pack['__display_zh'] = [list(x) for x in pairs()]
if which == 'en' and include_records:
from src.windscada.en_text import STANDARD_TERMS
if include_records == 'terms':
pack['__record_en'] = dict(STANDARD_TERMS)
else:
from src.windscada.data_tpl_en import RECORD_EN
pack['__record_en'] = dict(RECORD_EN, **STANDARD_TERMS)
# `` 出现在 JSON 里会提前闭合 script 标签; `<` 一律转义
packjs = json.dumps(pack, ensure_ascii=False).replace('<', '\\u003c')
return (_read('shell.html')
.replace('%LANG%', which)
.replace('%TITLE%', pack['app.title'])
.replace('%CSS%', _read('app.css'))
.replace('%LANGPACK%', packjs)
.replace('%CHARTS%', _read('charts.js'))
.replace('%JS%', _read('app.js')))
if __name__ == '__main__': # python -m app_frontEnd.app_frontEnd_guanlan.pages.build en > v2_en.html (旧路径 `python -m src.windscada.ui.build` 经兼容壳照旧可用)
import sys
sys.stdout.write(render(sys.argv[1] if len(sys.argv) > 1 else 'zh'))