anti-prestige-tool/reforger_queue/portal.py

75 lines
2.3 KiB
Python

import json
import os
import subprocess
import sys
from .config import PROJECT_DIR
def portal_helper_path():
return os.path.join(PROJECT_DIR, "portal_capture_frame")
def require_portal_helper():
helper = portal_helper_path()
if not os.path.exists(helper):
sys.exit(f"missing {helper}; run `make` in {PROJECT_DIR}")
if not os.access(helper, os.X_OK):
sys.exit(f"portal helper is not executable: {helper}")
return helper
def read_portal_restore_token(path):
try:
with open(path, "r", encoding="utf-8") as handle:
return handle.read().strip()
except FileNotFoundError:
return ""
except OSError as exc:
sys.exit(f"failed to read portal restore token {path}: {exc}")
def write_portal_restore_token(path, token):
directory = os.path.dirname(path)
if directory:
os.makedirs(directory, exist_ok=True)
temp_path = f"{path}.tmp"
try:
with open(temp_path, "w", encoding="utf-8") as handle:
handle.write(token)
handle.write("\n")
os.replace(temp_path, path)
except OSError as exc:
sys.exit(f"failed to write portal restore token {path}: {exc}")
def capture_portal_window(output, restore_token_path, reselect, timeout):
helper = require_portal_helper()
restore_token = ""
if restore_token_path and not reselect:
restore_token = read_portal_restore_token(restore_token_path)
command = [helper, "--window", output, "--timeout", str(timeout)]
if restore_token_path:
command.append("--persist")
if restore_token:
command.extend(["--restore-token", restore_token])
try:
result = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
except subprocess.CalledProcessError as exc:
message = exc.stderr.strip() if exc.stderr else str(exc)
sys.exit(message)
capture_info = {}
if result.stdout.strip():
try:
capture_info = json.loads(result.stdout)
except json.JSONDecodeError as exc:
sys.exit(f"failed to parse portal capture metadata: {exc}: {result.stdout!r}")
new_restore_token = str(capture_info.get("restore_token", "") or "")
if restore_token_path and new_restore_token:
write_portal_restore_token(restore_token_path, new_restore_token)
return capture_info