replx 1.6.2__tar.gz → 1.6.3__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.3}/PKG-INFO +1 -1
- {replx-1.6.2 → replx-1.6.3}/replx/__init__.py +1 -1
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/server/core.py +21 -29
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/server/handlers/exec.py +2 -3
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/server/handlers/transfer.py +20 -20
- {replx-1.6.2 → replx-1.6.3/replx.egg-info}/PKG-INFO +1 -1
- {replx-1.6.2 → replx-1.6.3}/LICENSE +0 -0
- {replx-1.6.2 → replx-1.6.3}/README.md +0 -0
- {replx-1.6.2 → replx-1.6.3}/pyproject.toml +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/client/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/client/core.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/client/session.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/protocol.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/server/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/server/__main__.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/server/command_dispatcher.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/server/connection_manager.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/server/handlers/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/server/handlers/filesystem.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/server/handlers/repl.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/server/handlers/session.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/agent/server/session_manager.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/app.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/commands/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/commands/device.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/commands/exec.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/commands/file.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/commands/firmware.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/commands/package.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/commands/utility.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/config.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/connection.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/helpers/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/helpers/compiler.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/helpers/environment.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/helpers/output.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/helpers/registry.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/helpers/scanner.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/helpers/store.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/cli/helpers/updater.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/commands.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/protocol/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/protocol/repl.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/protocol/storage.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/terminal.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/transport/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/transport/base.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/transport/serial.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/_thread.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/aioble/__init__.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/array.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/asyncio/__init__.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/binascii.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/bluetooth.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/builtins.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/cmath.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/collections.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/cryptolib.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/deflate.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/errno.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/framebuf.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/gc.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/hashlib.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/heapq.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/io.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/json.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/lwip.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/machine.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/math.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/micropython.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/mip/__init__.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/network.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/ntptime.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/os.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/platform.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/random.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/re.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/requests/__init__.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/select.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/socket.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/ssl.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/struct.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/sys.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/time.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/tls.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/uasyncio.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/uctypes.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/urequests.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm/vfs.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/binascii.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/errno.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/hashlib.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/io.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/json.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/machine.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/math.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/micropython.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/network.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/os.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/select.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/socket.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/ssl.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/struct.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/sys.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/time.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/ubinascii.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/ucryptolib.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/uerrno.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/uhashlib.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/uio.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/ujson.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/umachine.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/uos.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/uselect.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/usocket.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/ussl.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/ustruct.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/comm_separate/EFR32MG/utime.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/core/ESP32/aioespnow.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/core/ESP32/esp.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/core/ESP32/esp32.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/core/ESP32/espnow.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/core/MIMXRT1062DVJ6A/mimxrt.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/typehints/core/RP2350/rp2.pyi +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/utils/__init__.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/utils/constants.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/utils/device_info.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx/utils/exceptions.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx.egg-info/SOURCES.txt +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx.egg-info/dependency_links.txt +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx.egg-info/entry_points.txt +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx.egg-info/requires.txt +0 -0
- {replx-1.6.2 → replx-1.6.3}/replx.egg-info/top_level.txt +0 -0
- {replx-1.6.2 → replx-1.6.3}/setup.cfg +0 -0
- {replx-1.6.2 → replx-1.6.3}/test/test_line_mode_terminal.py +0 -0
- {replx-1.6.2 → replx-1.6.3}/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.3
|
|
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()
|
|
@@ -436,6 +431,19 @@ class AgentServer(
|
|
|
436
431
|
def _stop_drain_thread(self, conn: BoardConnection):
|
|
437
432
|
conn.stop_detached()
|
|
438
433
|
|
|
434
|
+
def _safe_send(self, data: bytes, addr: tuple) -> None:
|
|
435
|
+
"""Thread-safe UDP send via the asyncio transport.
|
|
436
|
+
Responses come from the agent's bound port (same as V1.0 behavior).
|
|
437
|
+
"""
|
|
438
|
+
transport = self._datagram_transport
|
|
439
|
+
loop = self._loop
|
|
440
|
+
if not transport or transport.is_closing() or not loop:
|
|
441
|
+
return
|
|
442
|
+
try:
|
|
443
|
+
loop.call_soon_threadsafe(transport.sendto, data, addr)
|
|
444
|
+
except Exception:
|
|
445
|
+
pass
|
|
446
|
+
|
|
439
447
|
def _stop_detached_script(self, conn: BoardConnection = None):
|
|
440
448
|
if conn:
|
|
441
449
|
if not conn.is_detached():
|
|
@@ -467,13 +475,10 @@ class AgentServer(
|
|
|
467
475
|
return
|
|
468
476
|
self.last_seq[client_addr] = seq
|
|
469
477
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
)
|
|
475
|
-
except Exception:
|
|
476
|
-
pass
|
|
478
|
+
self._safe_send(
|
|
479
|
+
AgentProtocol.encode_message(AgentProtocol.create_ack(seq)),
|
|
480
|
+
client_addr,
|
|
481
|
+
)
|
|
477
482
|
|
|
478
483
|
try:
|
|
479
484
|
ppid = msg.get('ppid')
|
|
@@ -492,13 +497,7 @@ class AgentServer(
|
|
|
492
497
|
except Exception as exc:
|
|
493
498
|
response = AgentProtocol.create_response(seq=seq, error=str(exc))
|
|
494
499
|
|
|
495
|
-
|
|
496
|
-
self.server_socket.sendto(
|
|
497
|
-
AgentProtocol.encode_message(response),
|
|
498
|
-
client_addr,
|
|
499
|
-
)
|
|
500
|
-
except Exception:
|
|
501
|
-
pass
|
|
500
|
+
self._safe_send(AgentProtocol.encode_message(response), client_addr)
|
|
502
501
|
|
|
503
502
|
def _handle_request(self, data: bytes, client_addr: tuple):
|
|
504
503
|
try:
|
|
@@ -524,13 +523,13 @@ class AgentServer(
|
|
|
524
523
|
|
|
525
524
|
ack = AgentProtocol.create_ack(seq)
|
|
526
525
|
ack_data = AgentProtocol.encode_message(ack)
|
|
527
|
-
self.
|
|
526
|
+
self._safe_send(ack_data, client_addr)
|
|
528
527
|
|
|
529
528
|
response = self._handle_message(msg, client_addr)
|
|
530
529
|
|
|
531
530
|
if response is not None:
|
|
532
531
|
response_data = AgentProtocol.encode_message(response)
|
|
533
|
-
self.
|
|
532
|
+
self._safe_send(response_data, client_addr)
|
|
534
533
|
|
|
535
534
|
except Exception as e:
|
|
536
535
|
try:
|
|
@@ -539,7 +538,7 @@ class AgentServer(
|
|
|
539
538
|
error=str(e)
|
|
540
539
|
)
|
|
541
540
|
error_data = AgentProtocol.encode_message(error_response)
|
|
542
|
-
self.
|
|
541
|
+
self._safe_send(error_data, client_addr)
|
|
543
542
|
except Exception:
|
|
544
543
|
pass
|
|
545
544
|
|
|
@@ -778,13 +777,6 @@ class AgentServer(
|
|
|
778
777
|
transport.close()
|
|
779
778
|
except Exception:
|
|
780
779
|
pass
|
|
781
|
-
elif self.server_socket:
|
|
782
|
-
try:
|
|
783
|
-
self.server_socket.close()
|
|
784
|
-
except Exception:
|
|
785
|
-
pass
|
|
786
|
-
self.server_socket = None
|
|
787
|
-
|
|
788
780
|
self._fast_executor.shutdown(wait=False, cancel_futures=True)
|
|
789
781
|
self._slow_executor.shutdown(wait=False, cancel_futures=True)
|
|
790
782
|
|
|
@@ -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.3
|
|
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
|