File

FILE: projects/phone_operator_bridge_deploy.py
SIZE: 3188 bytes
SHA256: 3a624bed0891f8ebe93d57f4329aea8ca897291bca76e5a489afaaa781b48ac1
Lines: 74

Use path as FILE | Patch Context | Read first 100 | Read prev 100 | Read next 100 | Git diff this file | Code Buffers | Active Patch Context

Blocks / Symbols (python)

LineTextActions
1
from pathlib import Path
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
2
import os, subprocess, re, json, secrets, hashlib, shutil
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
3
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
4
ROOT = Path(r"C:\Users\ash\PhoneOperatorBridge")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
5
ROOT.mkdir(parents=True, exist_ok=True)
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
6
SRC = Path(r"C:\Users\ash\Documents\Codex\2026-08-26\worked-for-1m-5s-inference-ya\projects\PhoneOperatorBridge_Code.gs")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
7
CLASP = r"C:\Users\ash\AppData\Roaming\npm\clasp.cmd"
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
8
ENV = os.environ.copy()
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
9
ENV["PATH"] = r"C:\Program Files\nodejs;C:\Users\ash\AppData\Roaming\npm;" + ENV.get("PATH","")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
10
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
11
if not SRC.exists():
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
12
    raise SystemExit("SOURCE_TEMPLATE_MISSING")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
13
template = SRC.read_text(encoding="utf-8")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
14
if "__PHONE_OPERATOR_BRIDGE_KEY__" not in template:
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
15
    raise SystemExit("SOURCE_TEMPLATE_PLACEHOLDER_MISSING")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
16
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
17
private_cfg = ROOT / "bridge_private.json"
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
18
existing_cfg = {}
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
19
if private_cfg.exists():
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
20
    existing_cfg = json.loads(private_cfg.read_text(encoding="utf-8"))
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
21
    key = existing_cfg.get("shared_key","")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
22
else:
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
23
    key = secrets.token_urlsafe(32)
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
24
if not key:
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
25
    raise SystemExit("PRIVATE_KEY_MISSING")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
26
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
27
(ROOT / "Code.gs").write_text(template.replace("__PHONE_OPERATOR_BRIDGE_KEY__", key), encoding="utf-8")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
28
(ROOT / "appsscript.json").write_text(json.dumps({
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
29
    "timeZone":"Asia/Kuala_Lumpur",
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
30
    "dependencies":{},
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
31
    "exceptionLogging":"STACKDRIVER",
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
32
    "runtimeVersion":"V8",
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
33
    "webapp":{"access":"ANYONE_ANONYMOUS","executeAs":"USER_DEPLOYING"}
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
34
}, separators=(",",":")), encoding="utf-8")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
35
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
36
def run(args, timeout=180):
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
37
    p = subprocess.run(args, cwd=str(ROOT), env=ENV, capture_output=True, text=True, timeout=timeout)
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
38
    print("$ " + " ".join(args))
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
39
    print(p.stdout, end="")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
40
    print(p.stderr, end="")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
41
    print("RC=" + str(p.returncode))
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
42
    if p.returncode != 0:
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
43
        raise SystemExit(p.returncode)
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
44
    return p.stdout + p.stderr
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
45
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
46
if not (ROOT / ".clasp.json").exists():
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
47
    run([CLASP,"create","--type","standalone","--title","Phone Operator Bridge","--rootDir","."])
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
48
run([CLASP,"push","-f"])
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
49
out = run([CLASP,"version","Phone Operator Bridge v1"])
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
50
m = re.search(r"Created version\s+(\d+)", out)
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
51
if not m:
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
52
    raise SystemExit("VERSION_PARSE_FAILED")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
53
version = m.group(1)
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
54
dep = str(existing_cfg.get("deployment_id", "")).strip()
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
55
if dep:
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
56
    # Update the existing deployment in place. Re-running setup must not
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
57
    # create a new Web App URL or leave duplicate deployments behind.
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
58
    run([CLASP,"deploy","-i",dep,"-V",version,"--description","Phone Operator Bridge v1"])
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
59
else:
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
60
    out = run([CLASP,"deploy","--versionNumber",version,"--description","Phone Operator Bridge v1"])
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
61
    m = re.search(r"(?:Deployed|Created deployment)\s+([A-Za-z0-9_-]+)\s+@", out)
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
62
    if not m:
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
63
        raise SystemExit("DEPLOYMENT_PARSE_FAILED")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
64
    dep = m.group(1)
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
65
endpoint = "https://script.google.com/macros/s/" + dep + "/exec"
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
66
private_cfg.write_text(json.dumps({
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
67
    "shared_key":key,
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
68
    "deployment_id":dep,
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
69
    "endpoint":endpoint
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
70
}, indent=2), encoding="utf-8")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
71
print("PHONE_OPERATOR_BRIDGE_DEPLOYMENT_UPDATED_IN_PLACE=" + ("yes" if existing_cfg.get("deployment_id") else "no_created_once"))
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
72
print("PHONE_OPERATOR_BRIDGE_ENDPOINT_SAVED=yes")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
73
print("PRIVATE_CONFIG_SAVED=yes")
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A
74
print("KEY_SHA256=" + hashlib.sha256(key.encode()).hexdigest())
Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A