Remove wrongly-specced opp-dm.py and dev-dm.py; dm.py is the headless DM tool
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Per-account session vitality check (runs INSIDE the node's netns).
|
||||
|
||||
Usage: sudo ip netns exec warp-<node> python3 accounts-health.py <cdp_port>
|
||||
|
||||
Probes the account's browser via CDP:
|
||||
- browser reachable
|
||||
- muse.ai tab present
|
||||
- login markers (heuristic: "Log in" button vs user content)
|
||||
|
||||
Prints JSON to stdout. Exit 0 on success, 1 if the browser is unreachable.
|
||||
"""
|
||||
import json, sys, urllib.request
|
||||
|
||||
CDP_PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 9410
|
||||
|
||||
def http(path, timeout=5):
|
||||
with urllib.request.urlopen(f"http://127.0.0.1:{CDP_PORT}{path}",
|
||||
timeout=timeout) as r:
|
||||
return json.loads(r.read())
|
||||
|
||||
result = {"browser_up": False, "muse_tab": False,
|
||||
"session_alive": None, "title": "", "url": "", "detail": ""}
|
||||
|
||||
try:
|
||||
http("/json/version")
|
||||
result["browser_up"] = True
|
||||
except Exception as e:
|
||||
result["detail"] = f"CDP unreachable: {e}"
|
||||
print(json.dumps(result)); sys.exit(1)
|
||||
|
||||
try:
|
||||
tabs = http("/json/list")
|
||||
except Exception as e:
|
||||
result["detail"] = f"tab list failed: {e}"
|
||||
print(json.dumps(result)); sys.exit(0)
|
||||
|
||||
muse_tab = None
|
||||
for t in tabs:
|
||||
url = t.get("url", "")
|
||||
if "muse.ai" in url and t.get("type") == "page":
|
||||
muse_tab = t
|
||||
break
|
||||
|
||||
if not muse_tab:
|
||||
result["detail"] = "no muse.ai tab open"
|
||||
print(json.dumps(result)); sys.exit(0)
|
||||
|
||||
result["muse_tab"] = True
|
||||
result["url"] = muse_tab.get("url", "")
|
||||
result["title"] = muse_tab.get("title", "")
|
||||
|
||||
# DOM heuristic via the tab's debugger socket
|
||||
try:
|
||||
import websocket
|
||||
ws = websocket.create_connection(muse_tab["webSocketDebuggerUrl"], timeout=10)
|
||||
js = """JSON.stringify({
|
||||
loginButtons: [...document.querySelectorAll('button')].filter(
|
||||
b => /^\\s*log\\s*in\\s*$/i.test(b.innerText)).map(b => b.innerText.trim()),
|
||||
hasAvatar: !!document.querySelector(
|
||||
'img[alt*="avatar" i], [data-testid*="avatar" i], [aria-label*="profile" i]'),
|
||||
title: document.title,
|
||||
url: location.href
|
||||
})"""
|
||||
ws.send(json.dumps({"id": 1, "method": "Runtime.evaluate",
|
||||
"params": {"expression": js, "returnByValue": True}}))
|
||||
resp = json.loads(ws.recv())
|
||||
ws.close()
|
||||
dom = json.loads(resp["result"]["result"]["value"])
|
||||
# Heuristic: login buttons present + no avatar => logged out.
|
||||
# No login buttons (or avatar present) => likely logged in.
|
||||
if dom["loginButtons"] and not dom["hasAvatar"]:
|
||||
result["session_alive"] = False
|
||||
result["detail"] = f"login wall visible: {dom['loginButtons'][:2]}"
|
||||
else:
|
||||
result["session_alive"] = True
|
||||
result["detail"] = "no login wall detected"
|
||||
except Exception as e:
|
||||
result["detail"] = f"DOM check failed: {e}"
|
||||
|
||||
print(json.dumps(result))
|
||||
Reference in New Issue
Block a user