ClipmanServer/build_web.py
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env python3
"""Build the server's architecture-independent browser assets outside source."""
import argparse
import hashlib
import json
import os
from pathlib import Path
import re
import shutil
import subprocess
import zlib
import base64
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--output', required=True, help='Empty folder outside the source tree')
parser.add_argument('--go', default='go', help='Go executable (1.26.8 or newer patched release)')
parser.add_argument('--server-output', help='Generated self-contained server script outside source')
args = parser.parse_args()
root = Path(__file__).resolve().parent.parent
output = Path(args.output).resolve()
if output == root or root in output.parents or output in root.parents:
parser.error('Browser output must be outside the source tree.')
if output.exists() and any(output.iterdir()):
parser.error('Browser output folder must be empty.')
version = subprocess.check_output([args.go, 'version'], text=True).strip()
match = re.search(r'go(\d+)\.(\d+)\.(\d+)', version)
if not match:
parser.error('A stable patched Go release is required.')
number = tuple(map(int, match.groups()))
if number < (1, 26, 8) or number == (1, 27, 0):
parser.error('Upgrade Go: the browser release requires fixed security vulnerabilities.')
output.mkdir(parents=True, exist_ok=True)
ui = root / 'ClipmanCli' / 'cmd' / 'clipman-web-preview' / 'ui'
for name in ['index.html', 'app.js', 'pagination.js', 'links.js', 'purify.min.js',
'rich.js', 'worker.js', 'style.css', 'DOMPurify-LICENSE.txt']:
shutil.copy2(ui / name, output / name)
goroot = subprocess.check_output([args.go, 'env', 'GOROOT'], text=True).strip()
shutil.copy2(Path(goroot) / 'lib' / 'wasm' / 'wasm_exec.js', output / 'wasm_exec.js')
shutil.copy2(root / 'ClipmanAndroid' / 'app' / 'src' / 'main' / 'res' / 'drawable-nodpi' / 'clipman_app_icon.png', output / 'icon.png')
env = dict(os.environ, GOOS='js', GOARCH='wasm', CGO_ENABLED='0')
subprocess.run([args.go, 'build', '-trimpath', '-o', str(output / 'client.wasm'), './cmd/clipman-web'],
cwd=root / 'ClipmanCli', env=env, check=True)
manifest = {'serverVersion': (root / 'ClipmanServer' / 'version.txt').read_text().strip(),
'goVersion': version.split()[2],
'sha256': {file.name: hashlib.sha256(file.read_bytes()).hexdigest()
for file in sorted(output.iterdir())}}
(output / 'browser-assets.json').write_text(json.dumps(manifest, indent=2) + '\n', encoding='utf-8')
if args.server_output:
target = Path(args.server_output).resolve()
if target == root or root in target.parents or target in root.parents or target.exists():
parser.error('Server output must be a new file outside the source tree.')
files = {file.name: base64.b64encode(file.read_bytes()).decode('ascii')
for file in sorted(output.iterdir())}
bundle = base64.b64encode(zlib.compress(json.dumps(files).encode(), level=9)).decode('ascii')
source = (root / 'ClipmanServerLinux' / 'clipman_server.py').read_text(encoding='utf-8')
marker = 'WEB_BUNDLE = ""'
if source.count(marker) != 1:
parser.error('Server browser bundle marker is missing or ambiguous.')
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text(source.replace(marker, 'WEB_BUNDLE = ' + repr(bundle)), encoding='utf-8')
print('Built browser assets for Clipman Server ' + manifest['serverVersion'])
if __name__ == '__main__':
main()