Skip to content

Commit 5ba559d

Browse files
committed
feat: Make py logging nicer
1 parent 1f37947 commit 5ba559d

File tree

1 file changed

+71
-66
lines changed

1 file changed

+71
-66
lines changed

src/main/resources/handler.py

Lines changed: 71 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,18 @@
2929
from pymobiledevice3.lockdown import create_using_usbmux
3030
import plistlib
3131

32+
class IPCClient:
33+
def __init__(self, sock, address):
34+
self.sock = sock
35+
self.read_file = sock.makefile('r')
36+
self.write_file = sock.makefile('w')
37+
self.address = address
38+
39+
def close(self):
40+
self.sock.close()
41+
self.read_file.close()
42+
self.write_file.close()
43+
3244
class WriteDispatcher:
3345
def __init__(self):
3446
self.write_queue = queue.Queue()
@@ -54,11 +66,11 @@ def _write_worker(self):
5466
finally:
5567
self.shutdown_event.set()
5668

57-
def write_reply(self, writer, reply: dict):
69+
def write_reply(self, ipc_client, reply: dict):
5870
if self.shutdown_event.is_set():
5971
return
60-
print("Sending packet: " + str(reply) + " to " + str(writer.fileno()))
61-
self.write_queue.put((writer, reply))
72+
print(f"{ipc_client.address}: Sending packet: {str(reply)}")
73+
self.write_queue.put((ipc_client.write_file, reply))
6274

6375
def shutdown(self):
6476
self.write_queue.put(None)
@@ -67,9 +79,7 @@ def shutdown(self):
6779
class ReadDispatcher:
6880
def __init__(self):
6981
self.socket_list = []
70-
self.addresses = {}
71-
self.read_files = {}
72-
self.write_files = {}
82+
self.clients = {}
7383
self.shutdown_event = threading.Event()
7484
self.read_thread = threading.Thread(target=self._read_worker, daemon=True, name="Python-ReadDispatcher")
7585
self.read_thread.start()
@@ -82,43 +92,38 @@ def _read_worker(self):
8292

8393
if self.shutdown_event.is_set():
8494
for sock in self.socket_list:
85-
self.remove_socket(sock)
95+
self.remove_client(self.clients[sock])
8696
return
8797

8898
for exception_socket in exception_sockets:
89-
self.remove_socket(exception_socket)
99+
self.remove_client(self.clients[exception_socket])
90100

91101
for ready_socket in ready_sockets:
92-
reader = self.read_files[ready_socket]
93-
writer = self.write_files[ready_socket]
94-
command = reader.readline().strip()
102+
ipc_client = self.clients[ready_socket]
103+
command = ipc_client.read_file.readline().strip()
95104
if not command:
96-
self.remove_socket(ready_socket)
105+
self.remove_client(ipc_client)
97106
continue
98-
print("Received command: {}".format(command))
107+
print(f"{ipc_client.address}: Received command: {command}")
99108

100-
handle_command(command, writer)
109+
handle_command(command, ipc_client)
101110

102111
except Exception as e:
103112
print(f"Read thread error: {e}")
104113
continue
105114
finally:
106115
self.shutdown_event.set()
107116

108-
def remove_socket(self, sock):
109-
self.socket_list.remove(sock)
110-
self.read_files.pop(sock).close()
111-
self.write_files.pop(sock).close()
112-
address = self.addresses.pop(sock)
113-
sock.close()
114-
print(f"Disconnected {address}")
117+
def remove_client(self, ipc_client):
118+
self.socket_list.remove(ipc_client.sock)
119+
self.clients.pop(ipc_client.sock)
120+
ipc_client.close()
121+
print(f"Disconnected {ipc_client.address}")
115122

116-
def add_socket(self, sock, address):
117-
self.read_files[sock] = sock.makefile('r')
118-
self.write_files[sock] = sock.makefile('w')
119-
self.addresses[sock] = address
120-
self.socket_list.append(sock)
121-
print(f"Connected {address}")
123+
def add_client(self, ipc_client):
124+
self.clients[ipc_client.sock] = ipc_client
125+
self.socket_list.append(ipc_client.sock)
126+
print(f"Connected {ipc_client.address}")
122127

123128

124129
def shutdown(self):
@@ -131,7 +136,7 @@ def shutdown(self):
131136
read_dispatcher = ReadDispatcher()
132137

133138

134-
def list_devices(id, writer):
139+
def list_devices(id, ipc_client):
135140
devices = []
136141
for device in usbmux.list_devices():
137142
udid = device.serial
@@ -141,33 +146,33 @@ def list_devices(id, writer):
141146

142147
reply = {"id": id, "state": "completed", "result": devices}
143148

144-
write_dispatcher.write_reply(writer, reply)
149+
write_dispatcher.write_reply(ipc_client, reply)
145150

146-
def list_devices_udid(id, writer):
151+
def list_devices_udid(id, ipc_client):
147152
devices = []
148153
for device in usbmux.list_devices():
149154
devices.append(device.serial)
150155

151156
reply = {"id": id, "state": "completed", "result": devices}
152157

153-
write_dispatcher.write_reply(writer, reply)
158+
write_dispatcher.write_reply(ipc_client, reply)
154159

155-
def get_device(id, device_id, writer):
160+
def get_device(id, device_id, ipc_client):
156161
try:
157162
with create_using_usbmux(device_id, autopair=False) as lockdown:
158163
reply = {"id": id, "state": "completed", "result": lockdown.short_info}
159-
write_dispatcher.write_reply(writer, reply)
164+
write_dispatcher.write_reply(ipc_client, reply)
160165
except NoDeviceConnectedError | DeviceNotFoundError:
161166
reply = {"id": id, "state": "failed_expected"}
162-
write_dispatcher.write_reply(writer, reply)
167+
write_dispatcher.write_reply(ipc_client, reply)
163168

164-
def install_app(id, lockdown_client, path, mode, writer):
169+
def install_app(id, lockdown_client, path, mode, ipc_client):
165170
with InstallationProxyService(lockdown=lockdown_client) as installer:
166171
options = {"PackageType": "Developer"}
167172

168173
def progress_handler(progress, *args):
169174
reply = {"id": id, "state": "progress", "progress": progress}
170-
write_dispatcher.write_reply(writer, reply)
175+
write_dispatcher.write_reply(ipc_client, reply)
171176
return
172177

173178
if mode == "INSTALL":
@@ -187,24 +192,24 @@ def progress_handler(progress, *args):
187192
res = installer.lookup(options={"BundleIDs" : [bundle_identifier]})
188193

189194
reply = {"id": id, "state": "completed", "result": res[bundle_identifier]["Path"]}
190-
write_dispatcher.write_reply(writer, reply)
195+
write_dispatcher.write_reply(ipc_client, reply)
191196

192197
print("Installed bundle: " + str(bundle_identifier))
193198

194-
def decode_plist(id, path, writer):
199+
def decode_plist(id, path, ipc_client):
195200
with open(path, 'rb') as f:
196201
plist_data = plistlib.load(f)
197202
reply = {"id": id, "state": "completed", "result": plist_data}
198-
write_dispatcher.write_reply(writer, reply)
203+
write_dispatcher.write_reply(ipc_client, reply)
199204
return
200205

201-
def auto_mount_image(id, lockdown, writer):
206+
def auto_mount_image(id, lockdown, ipc_client):
202207
try:
203208
asyncio.run(auto_mount(lockdown))
204209
except AlreadyMountedError:
205210
pass
206211
reply = {"id": id, "state": "completed"}
207-
write_dispatcher.write_reply(writer, reply)
212+
write_dispatcher.write_reply(ipc_client, reply)
208213

209214

210215
def start_tunneld():
@@ -261,14 +266,14 @@ def ensure_tunneld_running():
261266
else:
262267
print("tunneld is already running")
263268

264-
def debugserver_connect(id, lockdown, port, writer):
269+
def debugserver_connect(id, lockdown, port, ipc_client):
265270
try:
266271
discovery_service = get_tunneld_device_by_udid(lockdown.udid)
267272
if not discovery_service:
268273
raise TunneldConnectionError()
269274
except TunneldConnectionError:
270275
reply = {"id":id, "state": "failed_tunneld"}
271-
write_dispatcher.write_reply(writer, reply)
276+
write_dispatcher.write_reply(ipc_client, reply)
272277
return
273278

274279
if Version(discovery_service.product_version) < Version('17.0'):
@@ -293,10 +298,10 @@ def forwarder_thread():
293298
"host": "127.0.0.1",
294299
"port": selected_port
295300
}}
296-
write_dispatcher.write_reply(writer, reply)
301+
write_dispatcher.write_reply(ipc_client, reply)
297302

298303

299-
def debugserver_close(id, port, writer):
304+
def debugserver_close(id, port, ipc_client):
300305
forwarder, thread = active_debug_server.pop(port)
301306
forwarder.stop()
302307

@@ -306,10 +311,10 @@ def debugserver_close(id, port, writer):
306311
print(f"Joining debugserver thread {port} timed out")
307312

308313
reply = {"id": id, "state": "completed"}
309-
write_dispatcher.write_reply(writer, reply)
314+
write_dispatcher.write_reply(ipc_client, reply)
310315

311316

312-
def usbmux_forward_open(id, udid, remote_port, local_port, writer):
317+
def usbmux_forward_open(id, udid, remote_port, local_port, ipc_client):
313318
listen_event = threading.Event()
314319

315320
forwarder = UsbmuxTcpForwarder(udid, remote_port, local_port, listening_event=listen_event)
@@ -330,10 +335,10 @@ def forwarder_thread():
330335
"local_port": selected_port,
331336
"remote_port": remote_port
332337
}}
333-
write_dispatcher.write_reply(writer, reply)
338+
write_dispatcher.write_reply(ipc_client, reply)
334339

335340

336-
def usbmux_forward_close(id, local_port, writer):
341+
def usbmux_forward_close(id, local_port, ipc_client):
337342
forwarder, thread = active_usbmux_forwarder.pop(local_port)
338343
forwarder.stop()
339344

@@ -343,69 +348,69 @@ def usbmux_forward_close(id, local_port, writer):
343348
print(f"Joining usbmux thread {local_port} timed out")
344349

345350
reply = {"id": id, "state": "completed"}
346-
write_dispatcher.write_reply(writer, reply)
351+
write_dispatcher.write_reply(ipc_client, reply)
347352

348353

349-
def handle_command(command, writer):
354+
def handle_command(command, ipc_client):
350355
try:
351356
res = json.loads(command)
352357
id = res['id']
353358

354359
command_type = res['command']
355360
if command_type == "exit":
356-
print("Exiting by request")
361+
print(f"Exiting by request from {ipc_client.address}")
357362
atexit._run_exitfuncs()
358363
os._exit(0)
359364
elif command_type == "list_devices":
360-
list_devices(id, writer)
365+
list_devices(id, ipc_client)
361366
return
362367
elif command_type == "list_devices_udid":
363-
list_devices_udid(id, writer)
368+
list_devices_udid(id, ipc_client)
364369
return
365370
elif command_type == "get_device":
366371
device_id = res['device_id'] if 'device_id' in res else None
367-
get_device(id, device_id, writer)
372+
get_device(id, device_id, ipc_client)
368373
return
369374
elif command_type == "decode_plist":
370-
decode_plist(id, res['plist_path'], writer)
375+
decode_plist(id, res['plist_path'], ipc_client)
371376
return
372377
elif command_type == "debugserver_close":
373-
debugserver_close(id, res['port'], writer)
378+
debugserver_close(id, res['port'], ipc_client)
374379
return
375380
elif command_type == "usbmux_forwarder_open":
376-
usbmux_forward_open(id, res['device_id'], res['remote_port'], res['local_port'], writer)
381+
usbmux_forward_open(id, res['device_id'], res['remote_port'], res['local_port'], ipc_client)
377382
return
378383
elif command_type == "usbmux_forwarder_close":
379-
usbmux_forward_close(id, res['local_port'], writer)
384+
usbmux_forward_close(id, res['local_port'], ipc_client)
380385
return
381386
elif command_type == "ensure_tunneld_running":
382387
ensure_tunneld_running()
383388
reply = {"id": id, "state": "completed"}
384-
write_dispatcher.write_reply(writer, reply)
389+
write_dispatcher.write_reply(ipc_client, reply)
385390
return
386391
elif command_type == "is_tunneld_running":
387392
res = is_tunneld_running()
388393
reply = {"id": id, "state": "completed", "result": res}
389-
write_dispatcher.write_reply(writer, reply)
394+
write_dispatcher.write_reply(ipc_client, reply)
390395
return
391396

392397
# Now come the device targetted functions
393398
device_id = res['device_id']
394399
with create_using_usbmux(device_id) as lockdown:
395400
if command_type == "install_app":
396-
install_app(id, lockdown, res['app_path'], res['install_mode'], writer)
401+
install_app(id, lockdown, res['app_path'], res['install_mode'], ipc_client)
397402
return
398403
elif command_type == "auto_mount_image":
399-
auto_mount_image(id, lockdown, writer)
404+
auto_mount_image(id, lockdown, ipc_client)
400405
return
401406
elif command_type == "debugserver_connect":
402407
port = res['port'] if 'port' in res else 0
403-
debugserver_connect(id, lockdown, port, writer)
408+
debugserver_connect(id, lockdown, port, ipc_client)
404409
return
405410

406411
except Exception as e:
407412
reply = {"request": command, "state": "failed", "error": repr(e), "backtrace": traceback.format_exc()}
408-
write_dispatcher.write_reply(writer, reply)
413+
write_dispatcher.write_reply(ipc_client, reply)
409414

410415

411416
def main():
@@ -430,6 +435,6 @@ def main():
430435
print(f"Start listening on port {port}")
431436
while True:
432437
client_socket, client_address = server.accept()
433-
read_dispatcher.add_socket(client_socket, client_address)
438+
read_dispatcher.add_client(IPCClient(client_socket, client_address))
434439

435440
main()

0 commit comments

Comments
 (0)