| 1 | #!/usr/bin/env python3 |
| 2 | """Record one native input script, screenshot and page XML in an inspected clone.""" |
| 3 | import argparse |
| 4 | import base64 |
| 5 | import hashlib |
| 6 | import json |
| 7 | from pathlib import Path |
| 8 | import re |
| 9 | import sys |
| 10 | import xml.etree.ElementTree as ET |
| 11 | |
| 12 | sys.path.insert(0, str(Path(__file__).resolve().parents[1] / 'w7')) |
| 13 | import mcp_win7 as windows |
| 14 | |
| 15 | |
| 16 | def capture(target, page, script, output): |
| 17 | machine = json.loads((page.parent.parent / 'machine.json').read_text()) |
| 18 | if machine['name'] != target: |
| 19 | raise ValueError('The page belongs to a different native clone.') |
| 20 | page_id = ET.parse(page).getroot().attrib['ID'] |
| 21 | if not re.fullmatch(r'\{[0-9A-Fa-f-]+\}\{[0-9]+\}\{[0-9A-Fa-f]+\}', page_id): |
| 22 | raise ValueError('The page identity cannot be used for native export.') |
| 23 | source = script.read_bytes() |
| 24 | output.mkdir(parents=True, exist_ok=False) |
| 25 | result = windows.do_exec(source.decode('utf-8'), target=target, |
| 26 | timeout_ms=60000, shot_delay_ms=600) |
| 27 | record = {key: value for key, value in result.items() if key != 'png_b64'} |
| 28 | record.update(target=target, page_id=page_id, script=str(script.resolve()), |
| 29 | script_sha256=hashlib.sha256(source).hexdigest(), |
| 30 | source_xml_sha256=hashlib.sha256(page.read_bytes()).hexdigest()) |
| 31 | (output / 'input.json').write_text(json.dumps(record, indent=2) + '\n') |
| 32 | if result.get('error') or result.get('exit') != 0 or not result.get('png_b64'): |
| 33 | raise RuntimeError('Native input failed; inspect input.json.') |
| 34 | (output / 'screen.png').write_bytes(base64.b64decode(result['png_b64'], validate=True)) |
| 35 | remote = r'C:\one-tests\interaction.xml' |
| 36 | command = ('powershell -NoProfile -Command "' |
| 37 | "$app = New-Object -ComObject OneNote.Application; $xml = ''; " |
| 38 | f"$app.GetPageContent('{page_id}', [ref]$xml, 1, 1); " |
| 39 | f"[IO.File]::WriteAllText('{remote}', $xml, [Text.Encoding]::UTF8)\"") |
| 40 | result = windows.do_cmd(command, target=target) |
| 41 | (output / 'export.json').write_text(json.dumps(result, indent=2) + '\n') |
| 42 | if result.get('error') or result.get('exit') != 0: |
| 43 | raise RuntimeError('Native export failed; inspect export.json.') |
| 44 | result = windows.do_get(remote, output / 'page.xml', target) |
| 45 | if result.get('error'): |
| 46 | raise RuntimeError(result['error']) |
| 47 | |
| 48 | |
| 49 | if __name__ == '__main__': |
| 50 | parser = argparse.ArgumentParser(description=__doc__) |
| 51 | parser.add_argument('target') |
| 52 | parser.add_argument('page_xml', type=Path) |
| 53 | parser.add_argument('script', type=Path) |
| 54 | parser.add_argument('output', type=Path) |
| 55 | args = parser.parse_args() |
| 56 | capture(args.target, args.page_xml, args.script, args.output) |