82 lines
2.2 KiB
Python
Executable File
82 lines
2.2 KiB
Python
Executable File
#!/usr/bin/env -S uv run --script
|
|
# /// script
|
|
# requires-python = ">=3.11"
|
|
# dependencies = []
|
|
# ///
|
|
|
|
import json
|
|
import socket
|
|
import sys
|
|
import time
|
|
|
|
state, mode, text = sys.argv[1:4]
|
|
buttons = {
|
|
"up": ("/machine/adc", "adci[2]", 2242, 4095),
|
|
"down": ("/machine/adc", "adci[2]", 5, 4095),
|
|
"left": ("/machine/adc", "adci[1]", 1493, 4095),
|
|
"right": ("/machine/adc", "adci[1]", 5, 4095),
|
|
"select": ("/machine/adc", "adci[1]", 2694, 4095),
|
|
}
|
|
rows = ["1234567890", "qwertyuiop", "asdfghjkl", "zxcvbnm"]
|
|
widths = [10, 10, 9, 9, 6 if mode == "url" else 5]
|
|
keys = {char: (row, col) for row, chars in enumerate(rows) for col, char in enumerate(chars)}
|
|
if mode == "url":
|
|
keys.update({":": (4, 1), "/": (4, 2), ".": (4, 3)})
|
|
ok = (4, 5)
|
|
else:
|
|
ok = (4, 4)
|
|
|
|
sock = socket.socket(socket.AF_UNIX)
|
|
sock.connect(f"{state}/qmp.sock")
|
|
stream = sock.makefile("rw")
|
|
json.loads(stream.readline())
|
|
|
|
def command(execute, arguments=None):
|
|
payload = {"execute": execute}
|
|
if arguments is not None:
|
|
payload["arguments"] = arguments
|
|
stream.write(json.dumps(payload) + "\n")
|
|
stream.flush()
|
|
while True:
|
|
response = json.loads(stream.readline())
|
|
if "return" in response or "error" in response:
|
|
if "error" in response:
|
|
raise RuntimeError(response["error"])
|
|
return
|
|
|
|
command("qmp_capabilities")
|
|
|
|
def press(name):
|
|
path, prop, pressed, released = buttons[name]
|
|
command("qom-set", {"path": path, "property": prop, "value": pressed})
|
|
time.sleep(0.06)
|
|
command("qom-set", {"path": path, "property": prop, "value": released})
|
|
time.sleep(1 if name == "select" else 0.12)
|
|
|
|
row = col = 0
|
|
|
|
def move_to(target_row, target_col):
|
|
global row, col
|
|
while row:
|
|
old_width = widths[row]
|
|
press("up")
|
|
row -= 1
|
|
col = col * widths[row] // old_width
|
|
while col:
|
|
press("left")
|
|
col -= 1
|
|
while row < target_row:
|
|
old_width = widths[row]
|
|
press("down")
|
|
row += 1
|
|
col = col * widths[row] // old_width
|
|
while col < target_col:
|
|
press("right")
|
|
col += 1
|
|
|
|
for char in text.lower():
|
|
move_to(*keys[char])
|
|
press("select")
|
|
move_to(*ok)
|
|
press("select")
|