75 lines
2.3 KiB
Python
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
|