| 1 | #!/usr/bin/env python3 |
| 2 | """Apply keyboard controls during a native paragraph-fixture inspection.""" |
| 3 | import argparse |
| 4 | import base64 |
| 5 | import json |
| 6 | from pathlib import Path |
| 7 | import xml.etree.ElementTree as ET |
| 8 | |
| 9 | from native_runner import navigation_script, windows |
| 10 | from native_xml import ns |
| 11 | |
| 12 | |
| 13 | def apply(output): |
| 14 | target = json.loads((output / 'machine.json').read_text())['name'] |
| 15 | pages = {page.get('name'): page for path in (output / 'read').glob('page-*.xml') |
| 16 | for page in [ET.parse(path).getroot()]} |
| 17 | cases = json.loads((Path(__file__).resolve().parent.parent / |
| 18 | 'corpus/paragraph-edit/reconciliation/cases.json').read_text(encoding='utf-8-sig')) |
| 19 | scripts = output / 'keyboard' |
| 20 | scripts.mkdir() |
| 21 | for case in cases: |
| 22 | page = pages[case['name']] |
| 23 | paragraphs = page.findall('one:Outline/one:OEChildren/one:OE', ns) |
| 24 | join = case['operation'] == 'join' |
| 25 | change = case['change'] |
| 26 | at = 1 if join and change in ('child', 'list', 'tag', 'format', 'right-boundary') else 0 |
| 27 | keys = { |
| 28 | 'prefix': '{Left}X', |
| 29 | 'boundary': '{Right}X' if join else '{Left}{Right 2}X', |
| 30 | 'right-boundary': '{Left}X', |
| 31 | 'child': '{Right}{Enter}{Tab}Native child', |
| 32 | 'list': '{Left}^.', |
| 33 | 'tag': '{Left}^1', |
| 34 | 'format': '^i', |
| 35 | 'sibling': 'Native sibling', |
| 36 | 'adoption': '{Left}X', |
| 37 | }[change] |
| 38 | if change == 'sibling': |
| 39 | at = len(paragraphs) - 1 |
| 40 | steps = [(paragraphs[at].get('objectID'), keys)] |
| 41 | if join and change == 'prefix': |
| 42 | steps.append((paragraphs[1].get('objectID'), '{Right}Y')) |
| 43 | script = ''.join(navigation_script(page.get('ID'), oid) + f'Send "{keys}"\nSleep 300\n' |
| 44 | for oid, keys in steps) |
| 45 | stem = scripts / case['name'].lower().replace(' ', '-') |
| 46 | stem.with_suffix('.ahk').write_text(script) |
| 47 | result = windows.do_exec(script, target=target, shot_delay_ms=500) |
| 48 | stem.with_suffix('.json').write_text(json.dumps({k: v for k, v in result.items() if k != 'png_b64'}, indent=2)) |
| 49 | if result.get('png_b64'): |
| 50 | stem.with_suffix('.png').write_bytes(base64.b64decode(result['png_b64'])) |
| 51 | if result.get('error') or result.get('exit') != 0 or not result.get('png_b64'): |
| 52 | raise RuntimeError(windows.text_result(result)) |
| 53 | print(case['name'], flush=True) |
| 54 | (output / 'finish').touch() |
| 55 | |
| 56 | |
| 57 | if __name__ == '__main__': |
| 58 | parser = argparse.ArgumentParser(description=__doc__) |
| 59 | parser.add_argument('output', type=Path) |
| 60 | apply(parser.parse_args().output) |