#!/usr/bin/env python3 """ embed_for_dist.py ───────────────── Re-embeds edited source files back into Avaya_5952_setup.py for single-file distribution to end users. Run after editing source files: python embed_for_dist.py This is the reverse of extract_for_dev.py. """ import re, sys, ast from pathlib import Path HERE = Path(__file__).parent SETUP = HERE / "Avaya_5952_setup.py" if not SETUP.exists(): print(f"Error: {SETUP} not found") sys.exit(1) src = SETUP.read_text() # ── Helper: replace a repr()-encoded constant ─────────────────────────────── def replace_repr(src, name, new_value): idx = src.find(f'\n{name} = ') if idx == -1: print(f" Warning: {name} not found in setup script") return src start = idx + len(f'\n{name} = ') qc = src[start] end = start + 1 while end < len(src): if src[end] == qc and src[end-1] != '\\': end += 1; break end += 1 new_repr = repr(new_value) return src[:start] + new_repr + src[end:] # ── Helper: replace a triple-quoted constant ──────────────────────────────── def replace_triple(src, name, new_value): pattern = rf'({name}\s*=\s*""").*?(""")' replacement = r'\g<1>' + new_value.replace('\\', '\\\\') + r'\g<2>' new_src = re.sub(pattern, replacement, src, flags=re.DOTALL) if new_src == src: print(f" Warning: {name} not found or unchanged") return new_src # ── Files to embed ─────────────────────────────────────────────────────────── embeddings = [ # (embed_fn, source_filename, constant_name, note) (replace_repr, 'switch_backend.py', 'BACKEND_SRC', "FastAPI backend"), (replace_repr, 'ers5952-manager.jsx', 'JSX_SRC', "React frontend"), (replace_repr, 'README.md', 'README_SRC', "Documentation"), (replace_triple, 'Dockerfile', 'DOCKERFILE', "Docker image"), (replace_triple, 'docker-compose.yml', 'COMPOSE_YML', "Docker Compose"), ] print("Embedding source files into Avaya_5952_setup.py...\n") updated = src changed = [] for fn, fname, const, note in embeddings: fpath = HERE / fname if not fpath.exists(): print(f" ✗ {fname:<35} not found — skipping") continue content = fpath.read_text() new_src = fn(updated, const, content) if new_src != updated: updated = new_src changed.append(fname) print(f" ✓ {fname:<35} {note} ({len(content):,} chars)") else: print(f" – {fname:<35} unchanged") if not changed: print("\nNo changes — Avaya_5952_setup.py not modified") sys.exit(0) # ── Validate syntax before writing ────────────────────────────────────────── print("\nValidating Python syntax...") try: ast.parse(updated) print(" ✓ Syntax OK") except SyntaxError as e: print(f" ✗ Syntax error at line {e.lineno}: {e.msg}") print(" Avaya_5952_setup.py NOT modified — fix the error first") sys.exit(1) # ── Write ──────────────────────────────────────────────────────────────────── # Backup first backup = SETUP.with_suffix('.py.bak') backup.write_text(src) print(f" Backup saved to {backup.name}") SETUP.write_text(updated) import os size = os.path.getsize(SETUP) print(f"\n✓ Avaya_5952_setup.py updated ({size:,} bytes, {size//1024} KB)") print(f" {len(changed)} file(s) embedded: {', '.join(changed)}") print(""" The updated Avaya_5952_setup.py is ready for distribution. Test it: python Avaya_5952_setup.py """)