replx 1.6.2__tar.gz → 1.6.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {replx-1.6.2/replx.egg-info → replx-1.6.4}/PKG-INFO +1 -1
- {replx-1.6.2 → replx-1.6.4}/replx/__init__.py +1 -1
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/server/core.py +20 -30
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/server/handlers/exec.py +2 -3
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/server/handlers/transfer.py +20 -20
- {replx-1.6.2 → replx-1.6.4/replx.egg-info}/PKG-INFO +1 -1
- {replx-1.6.2 → replx-1.6.4}/LICENSE +0 -0
- {replx-1.6.2 → replx-1.6.4}/README.md +0 -0
- {replx-1.6.2 → replx-1.6.4}/pyproject.toml +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/client/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/client/core.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/client/session.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/protocol.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/server/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/server/__main__.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/server/command_dispatcher.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/server/connection_manager.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/server/handlers/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/server/handlers/filesystem.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/server/handlers/repl.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/server/handlers/session.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/agent/server/session_manager.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/app.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/commands/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/commands/device.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/commands/exec.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/commands/file.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/commands/firmware.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/commands/package.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/commands/utility.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/config.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/connection.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/helpers/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/helpers/compiler.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/helpers/environment.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/helpers/output.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/helpers/registry.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/helpers/scanner.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/helpers/store.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/cli/helpers/updater.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/commands.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/protocol/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/protocol/repl.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/protocol/storage.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/terminal.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/transport/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/transport/base.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/transport/serial.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/_thread.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/aioble/__init__.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/array.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/asyncio/__init__.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/binascii.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/bluetooth.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/builtins.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/cmath.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/collections.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/cryptolib.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/deflate.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/errno.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/framebuf.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/gc.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/hashlib.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/heapq.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/io.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/json.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/lwip.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/machine.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/math.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/micropython.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/mip/__init__.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/network.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/ntptime.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/os.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/platform.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/random.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/re.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/requests/__init__.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/select.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/socket.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/ssl.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/struct.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/sys.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/time.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/tls.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/uasyncio.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/uctypes.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/urequests.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm/vfs.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/binascii.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/errno.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/hashlib.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/io.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/json.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/machine.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/math.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/micropython.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/network.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/os.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/select.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/socket.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/ssl.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/struct.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/sys.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/time.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/ubinascii.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/ucryptolib.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/uerrno.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/uhashlib.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/uio.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/ujson.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/umachine.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/uos.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/uselect.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/usocket.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/ussl.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/ustruct.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/comm_separate/EFR32MG/utime.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/core/ESP32/aioespnow.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/core/ESP32/esp.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/core/ESP32/esp32.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/core/ESP32/espnow.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/core/MIMXRT1062DVJ6A/mimxrt.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/typehints/core/RP2350/rp2.pyi +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/utils/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/utils/constants.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/utils/device_info.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx/utils/exceptions.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx.egg-info/SOURCES.txt +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx.egg-info/dependency_links.txt +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx.egg-info/entry_points.txt +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx.egg-info/requires.txt +0 -0
- {replx-1.6.2 → replx-1.6.4}/replx.egg-info/top_level.txt +0 -0
- {replx-1.6.2 → replx-1.6.4}/setup.cfg +0 -0
- {replx-1.6.2 → replx-1.6.4}/test/test_line_mode_terminal.py +0 -0
- {replx-1.6.2 → replx-1.6.4}/test/test_termio.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: replx
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.4
|
|
4
4
|
Summary: replx is a fast, modern MicroPython CLI: turbo REPL, robust file sync (put/get), project install, mpy-cross integration, and smart port discovery.
|
|
5
5
|
Author-email: "chanmin.park" <devcamp@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -60,10 +60,6 @@ class _AgentDatagramProtocol(asyncio.DatagramProtocol):
|
|
|
60
60
|
def __init__(self, server: 'AgentServer') -> None:
|
|
61
61
|
self._server = server
|
|
62
62
|
|
|
63
|
-
def connection_made(self, transport: asyncio.DatagramTransport) -> None:
|
|
64
|
-
send_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
65
|
-
self._server.server_socket = send_sock
|
|
66
|
-
|
|
67
63
|
def datagram_received(self, data: bytes, addr: tuple) -> None:
|
|
68
64
|
server = self._server
|
|
69
65
|
if not server.running:
|
|
@@ -103,7 +99,6 @@ class AgentServer(
|
|
|
103
99
|
):
|
|
104
100
|
def __init__(self, port: int = None):
|
|
105
101
|
self.agent_port = port or DEFAULT_AGENT_PORT
|
|
106
|
-
self.server_socket: Optional[socket.socket] = None
|
|
107
102
|
self.running = False
|
|
108
103
|
|
|
109
104
|
self.connection_manager = ConnectionManager()
|
|
@@ -126,6 +121,7 @@ class AgentServer(
|
|
|
126
121
|
self._loop: asyncio.AbstractEventLoop | None = None
|
|
127
122
|
self._stop_event: asyncio.Event | None = None
|
|
128
123
|
self._datagram_transport: asyncio.DatagramTransport | None = None
|
|
124
|
+
self._send_socket: Optional[socket.socket] = None
|
|
129
125
|
self._cleaned_up: bool = False
|
|
130
126
|
|
|
131
127
|
@property
|
|
@@ -326,6 +322,7 @@ class AgentServer(
|
|
|
326
322
|
local_addr=(AGENT_HOST, self.agent_port),
|
|
327
323
|
)
|
|
328
324
|
self._datagram_transport = transport
|
|
325
|
+
self._send_socket = transport.get_extra_info('socket')
|
|
329
326
|
self.running = True
|
|
330
327
|
print(f'replx agent started — listening on {AGENT_HOST}:{self.agent_port} (UDP)')
|
|
331
328
|
|
|
@@ -436,6 +433,15 @@ class AgentServer(
|
|
|
436
433
|
def _stop_drain_thread(self, conn: BoardConnection):
|
|
437
434
|
conn.stop_detached()
|
|
438
435
|
|
|
436
|
+
def _safe_send(self, data: bytes, addr: tuple) -> None:
|
|
437
|
+
sock = self._send_socket
|
|
438
|
+
if not sock:
|
|
439
|
+
return
|
|
440
|
+
try:
|
|
441
|
+
sock.sendto(data, addr)
|
|
442
|
+
except Exception:
|
|
443
|
+
pass
|
|
444
|
+
|
|
439
445
|
def _stop_detached_script(self, conn: BoardConnection = None):
|
|
440
446
|
if conn:
|
|
441
447
|
if not conn.is_detached():
|
|
@@ -467,13 +473,10 @@ class AgentServer(
|
|
|
467
473
|
return
|
|
468
474
|
self.last_seq[client_addr] = seq
|
|
469
475
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
)
|
|
475
|
-
except Exception:
|
|
476
|
-
pass
|
|
476
|
+
self._safe_send(
|
|
477
|
+
AgentProtocol.encode_message(AgentProtocol.create_ack(seq)),
|
|
478
|
+
client_addr,
|
|
479
|
+
)
|
|
477
480
|
|
|
478
481
|
try:
|
|
479
482
|
ppid = msg.get('ppid')
|
|
@@ -492,13 +495,7 @@ class AgentServer(
|
|
|
492
495
|
except Exception as exc:
|
|
493
496
|
response = AgentProtocol.create_response(seq=seq, error=str(exc))
|
|
494
497
|
|
|
495
|
-
|
|
496
|
-
self.server_socket.sendto(
|
|
497
|
-
AgentProtocol.encode_message(response),
|
|
498
|
-
client_addr,
|
|
499
|
-
)
|
|
500
|
-
except Exception:
|
|
501
|
-
pass
|
|
498
|
+
self._safe_send(AgentProtocol.encode_message(response), client_addr)
|
|
502
499
|
|
|
503
500
|
def _handle_request(self, data: bytes, client_addr: tuple):
|
|
504
501
|
try:
|
|
@@ -524,13 +521,13 @@ class AgentServer(
|
|
|
524
521
|
|
|
525
522
|
ack = AgentProtocol.create_ack(seq)
|
|
526
523
|
ack_data = AgentProtocol.encode_message(ack)
|
|
527
|
-
self.
|
|
524
|
+
self._safe_send(ack_data, client_addr)
|
|
528
525
|
|
|
529
526
|
response = self._handle_message(msg, client_addr)
|
|
530
527
|
|
|
531
528
|
if response is not None:
|
|
532
529
|
response_data = AgentProtocol.encode_message(response)
|
|
533
|
-
self.
|
|
530
|
+
self._safe_send(response_data, client_addr)
|
|
534
531
|
|
|
535
532
|
except Exception as e:
|
|
536
533
|
try:
|
|
@@ -539,7 +536,7 @@ class AgentServer(
|
|
|
539
536
|
error=str(e)
|
|
540
537
|
)
|
|
541
538
|
error_data = AgentProtocol.encode_message(error_response)
|
|
542
|
-
self.
|
|
539
|
+
self._safe_send(error_data, client_addr)
|
|
543
540
|
except Exception:
|
|
544
541
|
pass
|
|
545
542
|
|
|
@@ -598,7 +595,6 @@ class AgentServer(
|
|
|
598
595
|
if not conn:
|
|
599
596
|
raise ValueError(f"Connection {target_port} not found")
|
|
600
597
|
|
|
601
|
-
# Disconnect handles stopping detached script and drain thread via stop_detached()
|
|
602
598
|
self.connection_manager.disconnect(target_port)
|
|
603
599
|
self.session_manager.remove_connection_from_all_sessions(target_port)
|
|
604
600
|
|
|
@@ -778,13 +774,7 @@ class AgentServer(
|
|
|
778
774
|
transport.close()
|
|
779
775
|
except Exception:
|
|
780
776
|
pass
|
|
781
|
-
|
|
782
|
-
try:
|
|
783
|
-
self.server_socket.close()
|
|
784
|
-
except Exception:
|
|
785
|
-
pass
|
|
786
|
-
self.server_socket = None
|
|
787
|
-
|
|
777
|
+
self._send_socket = None
|
|
788
778
|
self._fast_executor.shutdown(wait=False, cancel_futures=True)
|
|
789
779
|
self._slow_executor.shutdown(wait=False, cancel_futures=True)
|
|
790
780
|
|
|
@@ -199,7 +199,7 @@ class ExecCommandsMixin:
|
|
|
199
199
|
|
|
200
200
|
def send_error(msg: str):
|
|
201
201
|
error_response = AgentProtocol.create_response(seq=seq, error=msg)
|
|
202
|
-
self.
|
|
202
|
+
self._safe_send(AgentProtocol.encode_message(error_response), client_addr)
|
|
203
203
|
|
|
204
204
|
if not conn or not conn.repl_protocol:
|
|
205
205
|
send_error("Not connected")
|
|
@@ -273,7 +273,6 @@ class ExecCommandsMixin:
|
|
|
273
273
|
pass
|
|
274
274
|
|
|
275
275
|
def _run_interactive_thread(self, conn: BoardConnection, script_data: bytes):
|
|
276
|
-
sock = self.server_socket
|
|
277
276
|
client_addr = conn.interactive.client_addr
|
|
278
277
|
seq = conn.interactive.seq
|
|
279
278
|
|
|
@@ -293,7 +292,7 @@ class ExecCommandsMixin:
|
|
|
293
292
|
if completed:
|
|
294
293
|
msg['completed'] = True
|
|
295
294
|
msg['error'] = error
|
|
296
|
-
|
|
295
|
+
self._safe_send(AgentProtocol.encode_message(msg), client_addr)
|
|
297
296
|
except Exception:
|
|
298
297
|
pass
|
|
299
298
|
|
|
@@ -203,12 +203,12 @@ class TransferCommandsMixin:
|
|
|
203
203
|
if not conn or not conn.file_system:
|
|
204
204
|
error_response = AgentProtocol.create_response(seq=seq, error="Not connected")
|
|
205
205
|
error_data = AgentProtocol.encode_message(error_response)
|
|
206
|
-
self.
|
|
206
|
+
self._safe_send(error_data, client_addr)
|
|
207
207
|
return
|
|
208
208
|
|
|
209
209
|
ack_msg = AgentProtocol.create_ack(seq)
|
|
210
210
|
ack_data = AgentProtocol.encode_message(ack_msg)
|
|
211
|
-
self.
|
|
211
|
+
self._safe_send(ack_data, client_addr)
|
|
212
212
|
|
|
213
213
|
real_remote_path = self._to_real_path(remote_path, conn)
|
|
214
214
|
remote_normalized = real_remote_path.rstrip('/')
|
|
@@ -228,7 +228,7 @@ class TransferCommandsMixin:
|
|
|
228
228
|
"status": "starting"
|
|
229
229
|
})
|
|
230
230
|
progress_data = AgentProtocol.encode_message(progress_msg)
|
|
231
|
-
self.
|
|
231
|
+
self._safe_send(progress_data, client_addr)
|
|
232
232
|
|
|
233
233
|
files_downloaded = 0
|
|
234
234
|
|
|
@@ -277,7 +277,7 @@ class TransferCommandsMixin:
|
|
|
277
277
|
"status": "downloading"
|
|
278
278
|
})
|
|
279
279
|
progress_data = AgentProtocol.encode_message(progress_msg)
|
|
280
|
-
self.
|
|
280
|
+
self._safe_send(progress_data, client_addr)
|
|
281
281
|
|
|
282
282
|
final_response = AgentProtocol.create_response(seq=seq, result={
|
|
283
283
|
"downloaded_dir": remote_path,
|
|
@@ -286,12 +286,12 @@ class TransferCommandsMixin:
|
|
|
286
286
|
"success": True
|
|
287
287
|
})
|
|
288
288
|
final_data = AgentProtocol.encode_message(final_response)
|
|
289
|
-
self.
|
|
289
|
+
self._safe_send(final_data, client_addr)
|
|
290
290
|
|
|
291
291
|
except Exception as e:
|
|
292
292
|
error_response = AgentProtocol.create_response(seq=seq, error=f"getdir_to_local failed: {e}")
|
|
293
293
|
error_data = AgentProtocol.encode_message(error_response)
|
|
294
|
-
self.
|
|
294
|
+
self._safe_send(error_data, client_addr)
|
|
295
295
|
finally:
|
|
296
296
|
if conn:
|
|
297
297
|
conn.release()
|
|
@@ -351,18 +351,18 @@ class TransferCommandsMixin:
|
|
|
351
351
|
if not conn or not conn.file_system:
|
|
352
352
|
error_response = AgentProtocol.create_response(seq=seq, error="Not connected")
|
|
353
353
|
error_data = AgentProtocol.encode_message(error_response)
|
|
354
|
-
self.
|
|
354
|
+
self._safe_send(error_data, client_addr)
|
|
355
355
|
return
|
|
356
356
|
|
|
357
357
|
if not os.path.exists(local_path):
|
|
358
358
|
error_response = AgentProtocol.create_response(seq=seq, error=f"Local file not found: {local_path}")
|
|
359
359
|
error_data = AgentProtocol.encode_message(error_response)
|
|
360
|
-
self.
|
|
360
|
+
self._safe_send(error_data, client_addr)
|
|
361
361
|
return
|
|
362
362
|
|
|
363
363
|
ack_msg = AgentProtocol.create_ack(seq)
|
|
364
364
|
ack_data = AgentProtocol.encode_message(ack_msg)
|
|
365
|
-
self.
|
|
365
|
+
self._safe_send(ack_data, client_addr)
|
|
366
366
|
|
|
367
367
|
file_size = os.path.getsize(local_path)
|
|
368
368
|
file_name = os.path.basename(local_path)
|
|
@@ -374,7 +374,7 @@ class TransferCommandsMixin:
|
|
|
374
374
|
"status": "starting"
|
|
375
375
|
})
|
|
376
376
|
progress_data = AgentProtocol.encode_message(progress_msg)
|
|
377
|
-
self.
|
|
377
|
+
self._safe_send(progress_data, client_addr)
|
|
378
378
|
|
|
379
379
|
real_remote_path = self._to_real_path(remote_path, conn)
|
|
380
380
|
|
|
@@ -393,7 +393,7 @@ class TransferCommandsMixin:
|
|
|
393
393
|
"status": "uploading"
|
|
394
394
|
})
|
|
395
395
|
progress_data = AgentProtocol.encode_message(progress_msg)
|
|
396
|
-
self.
|
|
396
|
+
self._safe_send(progress_data, client_addr)
|
|
397
397
|
|
|
398
398
|
conn.file_system.put(local_path, real_remote_path, progress_callback=progress_callback)
|
|
399
399
|
bytes_uploaded[0] = file_size
|
|
@@ -405,13 +405,13 @@ class TransferCommandsMixin:
|
|
|
405
405
|
"success": True
|
|
406
406
|
})
|
|
407
407
|
final_data = AgentProtocol.encode_message(final_response)
|
|
408
|
-
self.
|
|
408
|
+
self._safe_send(final_data, client_addr)
|
|
409
409
|
|
|
410
410
|
except Exception as e:
|
|
411
411
|
error_response = AgentProtocol.create_response(seq=seq, error=str(e))
|
|
412
412
|
error_data = AgentProtocol.encode_message(error_response)
|
|
413
413
|
try:
|
|
414
|
-
self.
|
|
414
|
+
self._safe_send(error_data, client_addr)
|
|
415
415
|
except Exception:
|
|
416
416
|
pass
|
|
417
417
|
finally:
|
|
@@ -434,18 +434,18 @@ class TransferCommandsMixin:
|
|
|
434
434
|
if not conn or not conn.file_system:
|
|
435
435
|
error_response = AgentProtocol.create_response(seq=seq, error="Not connected")
|
|
436
436
|
error_data = AgentProtocol.encode_message(error_response)
|
|
437
|
-
self.
|
|
437
|
+
self._safe_send(error_data, client_addr)
|
|
438
438
|
return
|
|
439
439
|
|
|
440
440
|
if not os.path.exists(local_path) or not os.path.isdir(local_path):
|
|
441
441
|
error_response = AgentProtocol.create_response(seq=seq, error=f"Local directory not found: {local_path}")
|
|
442
442
|
error_data = AgentProtocol.encode_message(error_response)
|
|
443
|
-
self.
|
|
443
|
+
self._safe_send(error_data, client_addr)
|
|
444
444
|
return
|
|
445
445
|
|
|
446
446
|
ack_msg = AgentProtocol.create_ack(seq)
|
|
447
447
|
ack_data = AgentProtocol.encode_message(ack_msg)
|
|
448
|
-
self.
|
|
448
|
+
self._safe_send(ack_data, client_addr)
|
|
449
449
|
|
|
450
450
|
base_local = os.path.abspath(local_path)
|
|
451
451
|
real_remote_path = self._to_real_path(remote_path, conn)
|
|
@@ -481,7 +481,7 @@ class TransferCommandsMixin:
|
|
|
481
481
|
"status": "starting"
|
|
482
482
|
})
|
|
483
483
|
progress_data = AgentProtocol.encode_message(progress_msg)
|
|
484
|
-
self.
|
|
484
|
+
self._safe_send(progress_data, client_addr)
|
|
485
485
|
|
|
486
486
|
for dir_path in sorted(dirs_to_create):
|
|
487
487
|
try:
|
|
@@ -518,7 +518,7 @@ class TransferCommandsMixin:
|
|
|
518
518
|
"status": "uploading"
|
|
519
519
|
})
|
|
520
520
|
progress_data = AgentProtocol.encode_message(progress_msg)
|
|
521
|
-
self.
|
|
521
|
+
self._safe_send(progress_data, client_addr)
|
|
522
522
|
break
|
|
523
523
|
|
|
524
524
|
except Exception as e:
|
|
@@ -535,13 +535,13 @@ class TransferCommandsMixin:
|
|
|
535
535
|
"success": True
|
|
536
536
|
})
|
|
537
537
|
final_data = AgentProtocol.encode_message(final_response)
|
|
538
|
-
self.
|
|
538
|
+
self._safe_send(final_data, client_addr)
|
|
539
539
|
|
|
540
540
|
except Exception as e:
|
|
541
541
|
error_response = AgentProtocol.create_response(seq=seq, error=str(e))
|
|
542
542
|
error_data = AgentProtocol.encode_message(error_response)
|
|
543
543
|
try:
|
|
544
|
-
self.
|
|
544
|
+
self._safe_send(error_data, client_addr)
|
|
545
545
|
except Exception:
|
|
546
546
|
pass
|
|
547
547
|
finally:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: replx
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.4
|
|
4
4
|
Summary: replx is a fast, modern MicroPython CLI: turbo REPL, robust file sync (put/get), project install, mpy-cross integration, and smart port discovery.
|
|
5
5
|
Author-email: "chanmin.park" <devcamp@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|