1"""Delete and type over selections crossing a table's edge in OneNote 2010 and capture what
2it stores. The oracle for the canvas editor's cross-container deletion.
3
4Usage: native_cross_container.py NOTEBOOK_DIR OUTPUT_DIR
5"""
6import base64
7import json
8import sys
9from pathlib import Path
10import xml.etree.ElementTree as ET
11
12sys.path.insert(0, str(Path(__file__).resolve().parent))
13import native_runner as runner
14from native_xml import ns
15
16windows = runner.windows
17
18# Each page's keys once the caret stands in the line clicked: from "Before" into "Alpha one",
19# from "Alpha two" out to "After", from "Before" over the whole first row into "Beta one",
20# and from "Before" over the whole table into "After".
21KEYS = {
22 'Delete into a table': ((160, 236), '{Home}{Right 6}', 11, 'Send("{Delete}")'),
23 'Delete out of a table': ((250, 260), '{Home}{Right 5}', 28, 'Send("{Delete}")\nSleep(500)\nSendText("X")'),
24 'Type over a row': ((160, 236), '{Home}{Right 6}', 30, 'SendText("Y")'),
25 'Delete a whole table': ((160, 236), '{Home}{Right 6}', 49, 'Send("{Delete}")'),
26}
27
28
29def interaction(name, output):
30 pages = {}
31 for path in sorted((output / 'read').glob('page-*.xml')):
32 page = ET.parse(path).getroot()
33 title = page.find('one:Title/one:OE/one:T', ns)
34 if title is not None and title.text in KEYS:
35 pages[title.text] = page.attrib['ID']
36 for title, ((x, y), place, extend, action) in KEYS.items():
37 script = '''ComObject("OneNote.Application").NavigateTo("%s", "", false)
38WinWait("ahk_exe ONENOTE.EXE", , 30)
39WinActivate("ahk_exe ONENOTE.EXE")
40WinWaitActive("ahk_exe ONENOTE.EXE", , 30)
41WinMaximize("ahk_exe ONENOTE.EXE")
42Sleep(3000)
43CoordMode("Mouse", "Screen")
44Click(%d, %d)
45Sleep(500)
46Send("%s")
47Sleep(300)
48Send("+{Right %d}")
49Sleep(500)
50%s
51Sleep(2000)
52''' % (pages[title], x, y, place, extend, action)
53 stem = title.lower().replace(' ', '-')
54 (output / (stem + '.ahk')).write_text(script)
55 result = windows.do_exec(script, target=name, timeout_ms=120000, shot_delay_ms=1500)
56 screenshot = result.pop('png_b64', None)
57 if screenshot:
58 (output / (stem + '.png')).write_bytes(base64.b64decode(screenshot))
59 (output / (stem + '.json')).write_text(json.dumps(result, indent=2))
60 if result.get('error') or result.get('exit') != 0:
61 raise RuntimeError(str(result))
62
63
64if __name__ == '__main__':
65 notebook, output = Path(sys.argv[1]), Path(sys.argv[2])
66 runner.capture(notebook, output, expected_pages=-1, collect_notebook=True, interaction=interaction)