#!/usr/bin/env python3 # -*- coding: utf-8 -*- r"""构建后放置**非 vite 产物**的静态件(P22 实逮:`vite build` 会清空 `release/web`,先放后建必被清掉)。 放置内容: · `release/web/portal/` —— 门户件(shell.html + governance_sources.json + manifest.json + templates/28 件) · `release/web/detail_v2.html` —— v2.9.2 原文经典页(仅作对照/回退视图) · `release/web/favicon.svg` 来源:`app_guanlang_v2.9.2.zip`(参考包,存在则用;可用 `--zip` 指定)。经典页用 v2.9.2 自带 `src/windscada/ui/build.py` 出页(含语言包),保证与 v2.9.2 一致。 用法:python scripts/place_static_extras.py [--zip ](或设环境变量 GUANLAN_REF_PKG) """ from __future__ import annotations import argparse import os import pathlib import shutil import subprocess import sys import tempfile import zipfile HERE = pathlib.Path(__file__).resolve().parents[1] REL = HERE / 'release' / 'web' # 参考包路径**不硬编码**(可移植性门禁):由 --zip 或环境变量 GUANLAN_REF_PKG 提供 DEFAULT_ZIP = os.environ.get('GUANLAN_REF_PKG') or '' def main() -> int: ap = argparse.ArgumentParser() ap.add_argument('--zip', default=DEFAULT_ZIP, help='v2.9.2 参考包(或用环境变量 GUANLAN_REF_PKG)') a = ap.parse_args() if not a.zip: print('[X] 未提供参考包路径:请用 --zip 或设环境变量 GUANLAN_REF_PKG;' '(跳过;门户件与经典页保持现状)') return 2 zp = pathlib.Path(a.zip) if not zp.exists(): print('[X] 参考包不在:%s(跳过;门户件与经典页保持现状)' % zp) return 2 # 门户件 out = REL / 'portal' if out.exists(): shutil.rmtree(out) (out / 'templates').mkdir(parents=True, exist_ok=True) with zipfile.ZipFile(zp) as z: (out / 'shell.html').write_bytes(z.read('release/portal_src/shell.html')) (out / 'governance_sources.json').write_bytes(z.read('release/portal_src/governance_sources.json')) (out / 'manifest.json').write_bytes(z.read('release/portal_src/manifest.json')) n = 0 for nm in z.namelist(): if nm.startswith('release/portal_src/templates/'): (out / 'templates' / pathlib.Path(nm).name).write_bytes(z.read(nm)) n += 1 (REL / 'favicon.svg').write_bytes(z.read('src/windscada/ui/favicon.svg')) # 经典页:解出 src/ 与 configs/ 后用其自带 build.py 出页 tmp = pathlib.Path(tempfile.mkdtemp(prefix='gl_v292_')) want = [m for m in z.namelist() if m.startswith('src/') or m.startswith('configs/')] z.extractall(tmp, members=want) pyx = HERE / '.venv' / 'Scripts' / 'python.exe' p = subprocess.run([str(pyx), '-X', 'utf8', '-m', 'src.windscada.ui.build', 'zh'], cwd=str(tmp), capture_output=True, timeout=900) if p.returncode == 0 and p.stdout: (REL / 'detail_v2.html').write_bytes(p.stdout) shutil.rmtree(tmp, ignore_errors=True) print('[OK] 门户件 shell + %d 模板 · favicon · 经典页 %s' % (n, '已出页' if (REL / 'detail_v2.html').exists() else '未出页')) return 0 if __name__ == '__main__': raise SystemExit(main())