app
Fusion - the Fusion 360 Bridge
Public Made by Adomby adom
Drive Autodesk Fusion 360 from the cloud via Adom Bridge: component libraries, IPC package generation, board layout, exports (STEP/Gerbers/BOM/CPL), fast APS cloud search, and parametric modeling.
← Commit history
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 "