← Commit history

Upload 1 file(s)

John Lauer ·814fbfbd3b ·2mo ago ·parent 5a3c224
1 file changed +54
server.py+54
@@ -3731,6 +3731,41 @@ def _chrome_authorize_urls(max_age_min: int = 15):     return found  +def _fusion_click_signin() -> bool:+    """Click Fusion's 'Welcome to Fusion' -> Sign In button SERVER-SIDE (it is a webview with+    no UIA node, so image-space click). Returns True if a click was dispatched. Runs on-box so+    it adds no remote round-trip to the ~2-min OAuth window."""+    rd = _handle_fusion_readiness({}, {})+    hwnd = rd.get("hwnd") or rd.get("windowHandle")+    shot = _ad_call("desktop_screenshot_window", {"hwnd": hwnd} if hwnd else {"titleContains": "Autodesk Fusion"}, timeout=45)+    sd = shot.get("data", shot) if isinstance(shot, dict) else {}+    cm = sd.get("coordMap") or {}+    sid = cm.get("shotId") or sd.get("shotId")+    w = sd.get("width") or 1400; h = sd.get("height") or 860+    if not sid:+        return False+    # the Sign In button sits centered, ~57% down the welcome screen+    _ad_call("desktop_click", {"space": "image", "shotId": sid,+                               "x": int(w * 0.5), "y": int(h * 0.57)}, timeout=30)+    return True+++def _capture_fresh_authorize(wait_sec: int = 30, max_age: int = 120):+    """Poll the browser History for a FRESH (< max_age s) Fusion authorize URL for up to+    wait_sec, ON-BOX. Collapsing capture into one server-side wait (instead of the caller+    re-polling over the flaky relay) is what lets the whole chain finish inside Fusion's+    ~2-min request window. Returns the auth dict or None."""+    import time as _t+    deadline = _t.time() + max(1, wait_sec)+    while True:+        urls = _chrome_authorize_urls()+        if urls and urls[0]["ageSec"] <= max_age:+            return urls[0]+        if _t.time() >= deadline:+            return urls[0] if urls else None+        _t.sleep(2)++ def _orchestrate_signin(args: dict) -> dict:     """Sign Fusion in through the CORRECT browser profile - the fix for Fusion firing its     OAuth at the OS-default browser (often the wrong Autodesk account). See the@@ -3739,8 +3774,15 @@ def _orchestrate_signin(args: dict) -> dict:     Staged: pick the target profile (remembered / arg / probed / ask) -> ensure Fusion has     emitted its OAuth URL (click Sign In if not) -> read that URL from the wrong browser's     History -> re-open it in the TARGET profile in the BACKGROUND -> report where it waits.++    auto=True runs the whole chain in ONE server-side call: click Fusion's Sign In, poll on-box+    for the fresh authorize URL, then re-open it in the target profile - so the capture->reopen+    round-trips happen on the box (fast) and fit inside Fusion's ~2-min request expiry even when+    the remote relay is slow. This is the reliable path; the staged/manual path is the fallback.     """     steps = []+    auto = bool(args.get("auto"))+    wait_sec = int(args.get("waitSec") or 32)     target = args.get("profile")           # explicit override, e.g. "chrome:[email protected]"     if target:         _remember_signin_profile(target)@@ -3765,6 +3807,18 @@ def _orchestrate_signin(args: dict) -> dict:      # read Fusion's authorize URL from browser history (it fires the OS-default browser)     urls = _chrome_authorize_urls()+    fresh = urls[0] if (urls and urls[0]["ageSec"] <= 150) else None+    if auto and not fresh:+        # ONE server-side pass: click Fusion's Sign In, then poll on-box for the fresh URL.+        clicked = _fusion_click_signin()+        steps.append("clicked Fusion 'Sign In'" if clicked else "could not click Fusion 'Sign In'")+        got = _capture_fresh_authorize(wait_sec=wait_sec, max_age=140)+        if got and got["ageSec"] <= 150:+            urls = [got]+        elif got:+            urls = [got]  # stale; fall through to the stale branch which tells us to reset+        else:+            urls = []     if not urls:         return {"success": True, "stage": "click_signin", "done": False, "steps": steps,                 "_hint": ("No recent Fusion OAuth URL in any browser's history yet - Fusion has not "