mdify-cli 3.0.5__tar.gz → 3.0.6__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.
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/PKG-INFO +1 -1
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify/__init__.py +1 -1
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify/cli.py +65 -24
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify_cli.egg-info/PKG-INFO +1 -1
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/pyproject.toml +1 -1
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/LICENSE +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/README.md +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/assets/mdify.png +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify/__main__.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify/container.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify/docling_client.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify/formatting.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify/ssh/__init__.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify/ssh/client.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify/ssh/models.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify/ssh/remote_container.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify/ssh/transfer.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify_cli.egg-info/SOURCES.txt +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify_cli.egg-info/dependency_links.txt +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify_cli.egg-info/entry_points.txt +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify_cli.egg-info/requires.txt +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/mdify_cli.egg-info/top_level.txt +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/setup.cfg +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/tests/test_cli.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/tests/test_container.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/tests/test_docling_client.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.6}/tests/test_ssh_client.py +0 -0
|
@@ -1107,17 +1107,17 @@ def main_async_remote(args) -> int:
|
|
|
1107
1107
|
|
|
1108
1108
|
# Connect to remote server
|
|
1109
1109
|
if not args.quiet:
|
|
1110
|
-
print(f"Connecting to {ssh_config.host}:{ssh_config.port}...", file=sys.stderr)
|
|
1110
|
+
print(color.cyan(f"Connecting to {ssh_config.host}:{ssh_config.port}..."), file=sys.stderr)
|
|
1111
1111
|
|
|
1112
1112
|
await ssh_client.connect()
|
|
1113
1113
|
|
|
1114
1114
|
if not args.quiet:
|
|
1115
|
-
print(f"✓ Connected to {ssh_config.host}", file=sys.stderr)
|
|
1115
|
+
print(color.green(f"✓ Connected to {ssh_config.host}"), file=sys.stderr)
|
|
1116
1116
|
|
|
1117
1117
|
# Validate remote resources if not skipped
|
|
1118
1118
|
if not args.remote_skip_validation:
|
|
1119
1119
|
if not args.quiet:
|
|
1120
|
-
print("Validating remote resources...", file=sys.stderr)
|
|
1120
|
+
print(color.cyan("Validating remote resources..."), file=sys.stderr)
|
|
1121
1121
|
|
|
1122
1122
|
validation_result = await ssh_client.validate_remote_resources()
|
|
1123
1123
|
|
|
@@ -1152,7 +1152,7 @@ def main_async_remote(args) -> int:
|
|
|
1152
1152
|
return 130
|
|
1153
1153
|
|
|
1154
1154
|
if not args.quiet:
|
|
1155
|
-
print("✓ All remote resources validated", file=sys.stderr)
|
|
1155
|
+
print(color.green("✓ All remote resources validated"), file=sys.stderr)
|
|
1156
1156
|
|
|
1157
1157
|
# If --remote-validate-only, exit here
|
|
1158
1158
|
if args.remote_validate_only:
|
|
@@ -1178,7 +1178,7 @@ def main_async_remote(args) -> int:
|
|
|
1178
1178
|
return 1
|
|
1179
1179
|
|
|
1180
1180
|
if not args.quiet:
|
|
1181
|
-
print(f"\nFound {len(files_to_convert)} file(s) to convert", file=sys.stderr)
|
|
1181
|
+
print(color.cyan(f"\nFound {len(files_to_convert)} file(s) to convert"), file=sys.stderr)
|
|
1182
1182
|
|
|
1183
1183
|
# Import remote container and transfer manager
|
|
1184
1184
|
from mdify.ssh.transfer import FileTransferManager
|
|
@@ -1223,12 +1223,12 @@ def main_async_remote(args) -> int:
|
|
|
1223
1223
|
|
|
1224
1224
|
# Start remote container
|
|
1225
1225
|
if not args.quiet:
|
|
1226
|
-
print(f"\nStarting remote container ({image})...", file=sys.stderr)
|
|
1226
|
+
print(color.cyan(f"\nStarting remote container ({image})..."), file=sys.stderr)
|
|
1227
1227
|
|
|
1228
1228
|
try:
|
|
1229
1229
|
await remote_container.start()
|
|
1230
1230
|
if not args.quiet:
|
|
1231
|
-
print(f"✓ Container started: {remote_container.state.container_name}", file=sys.stderr)
|
|
1231
|
+
print(color.green(f"✓ Container started: {remote_container.state.container_name}"), file=sys.stderr)
|
|
1232
1232
|
except Exception as e:
|
|
1233
1233
|
await ssh_client.disconnect()
|
|
1234
1234
|
print(f"Error: Failed to start remote container: {e}", file=sys.stderr)
|
|
@@ -1319,10 +1319,48 @@ def main_async_remote(args) -> int:
|
|
|
1319
1319
|
convert_cmd += f"-F 'mask=true' "
|
|
1320
1320
|
convert_cmd += f"http://localhost:{args.port}/v1/convert/file"
|
|
1321
1321
|
|
|
1322
|
-
|
|
1322
|
+
# Retry conversion command with exponential backoff
|
|
1323
|
+
conversion_attempt = 0
|
|
1324
|
+
conversion_success = False
|
|
1325
|
+
while conversion_attempt < 3:
|
|
1326
|
+
try:
|
|
1327
|
+
stdout, stderr, code = await ssh_client.run_command(convert_cmd, timeout=timeout)
|
|
1328
|
+
|
|
1329
|
+
if code == 0:
|
|
1330
|
+
conversion_success = True
|
|
1331
|
+
break
|
|
1332
|
+
elif is_connection_error(Exception(stderr)) and conversion_attempt < 2:
|
|
1333
|
+
conversion_attempt += 1
|
|
1334
|
+
if not args.quiet:
|
|
1335
|
+
print(f" ↻ Conversion attempt {conversion_attempt}: reconnecting...", file=sys.stderr)
|
|
1336
|
+
try:
|
|
1337
|
+
await ssh_client.disconnect()
|
|
1338
|
+
except Exception:
|
|
1339
|
+
pass
|
|
1340
|
+
await ssh_client.connect()
|
|
1341
|
+
continue
|
|
1342
|
+
else:
|
|
1343
|
+
if not args.quiet:
|
|
1344
|
+
print(f" ✗ Conversion failed (curl error code {code}): {stderr}", file=sys.stderr)
|
|
1345
|
+
break
|
|
1346
|
+
except Exception as conv_exc:
|
|
1347
|
+
if is_connection_error(conv_exc) and conversion_attempt < 2:
|
|
1348
|
+
conversion_attempt += 1
|
|
1349
|
+
if not args.quiet:
|
|
1350
|
+
print(f" ↻ Conversion attempt {conversion_attempt}: reconnecting...", file=sys.stderr)
|
|
1351
|
+
try:
|
|
1352
|
+
await ssh_client.disconnect()
|
|
1353
|
+
except Exception:
|
|
1354
|
+
pass
|
|
1355
|
+
await ssh_client.connect()
|
|
1356
|
+
continue
|
|
1357
|
+
else:
|
|
1358
|
+
raise conv_exc
|
|
1359
|
+
|
|
1360
|
+
conversion_attempt += 1
|
|
1323
1361
|
|
|
1324
|
-
if
|
|
1325
|
-
print(f" ✗ Conversion failed
|
|
1362
|
+
if not conversion_success:
|
|
1363
|
+
print(f" ✗ Failed: Conversion failed after {conversion_attempt} attempt(s)", file=sys.stderr)
|
|
1326
1364
|
failed += 1
|
|
1327
1365
|
break
|
|
1328
1366
|
|
|
@@ -1380,7 +1418,7 @@ def main_async_remote(args) -> int:
|
|
|
1380
1418
|
|
|
1381
1419
|
# Download result
|
|
1382
1420
|
if not args.quiet:
|
|
1383
|
-
print(f" Downloading result to {output_file}...", file=sys.stderr)
|
|
1421
|
+
print(color.cyan(f" Downloading result to {output_file}..."), file=sys.stderr)
|
|
1384
1422
|
|
|
1385
1423
|
await transfer_manager.download_file(
|
|
1386
1424
|
remote_path=remote_output_path,
|
|
@@ -1389,7 +1427,7 @@ def main_async_remote(args) -> int:
|
|
|
1389
1427
|
)
|
|
1390
1428
|
|
|
1391
1429
|
if not args.quiet:
|
|
1392
|
-
print(f" ✓ Download complete: {output_file}", file=sys.stderr)
|
|
1430
|
+
print(color.green(f" ✓ Download complete: {output_file}"), file=sys.stderr)
|
|
1393
1431
|
|
|
1394
1432
|
successful += 1
|
|
1395
1433
|
|
|
@@ -1401,7 +1439,7 @@ def main_async_remote(args) -> int:
|
|
|
1401
1439
|
if is_connection_error(e) and attempt == 0:
|
|
1402
1440
|
attempt += 1
|
|
1403
1441
|
if not args.quiet:
|
|
1404
|
-
print(" ↻ Connection lost. Reconnecting...", file=sys.stderr)
|
|
1442
|
+
print(color.yellow(" ↻ Connection lost. Reconnecting..."), file=sys.stderr)
|
|
1405
1443
|
try:
|
|
1406
1444
|
await ssh_client.disconnect()
|
|
1407
1445
|
except Exception:
|
|
@@ -1419,21 +1457,21 @@ def main_async_remote(args) -> int:
|
|
|
1419
1457
|
finally:
|
|
1420
1458
|
# Stop and remove container
|
|
1421
1459
|
if not args.quiet:
|
|
1422
|
-
print(f"\nStopping remote container...", file=sys.stderr)
|
|
1460
|
+
print(color.cyan(f"\nStopping remote container..."), file=sys.stderr)
|
|
1423
1461
|
|
|
1424
1462
|
try:
|
|
1425
1463
|
await remote_container.stop(force=False)
|
|
1426
1464
|
if not args.quiet:
|
|
1427
|
-
print(f"✓ Container stopped", file=sys.stderr)
|
|
1465
|
+
print(color.green(f"✓ Container stopped"), file=sys.stderr)
|
|
1428
1466
|
except Exception as e:
|
|
1429
1467
|
if not args.quiet:
|
|
1430
|
-
print(f"Warning: Failed to stop container: {e}", file=sys.stderr)
|
|
1468
|
+
print(color.yellow(f"Warning: Failed to stop container: {e}"), file=sys.stderr)
|
|
1431
1469
|
|
|
1432
1470
|
# Cleanup remote work directory
|
|
1433
1471
|
try:
|
|
1434
1472
|
await ssh_client.run_command(f"rm -rf {work_dir}")
|
|
1435
1473
|
if not args.quiet:
|
|
1436
|
-
print(f"✓ Cleaned up remote directory", file=sys.stderr)
|
|
1474
|
+
print(color.green(f"✓ Cleaned up remote directory"), file=sys.stderr)
|
|
1437
1475
|
except Exception as e:
|
|
1438
1476
|
if not args.quiet:
|
|
1439
1477
|
print(f"Warning: Failed to cleanup remote directory: {e}", file=sys.stderr)
|
|
@@ -1442,21 +1480,24 @@ def main_async_remote(args) -> int:
|
|
|
1442
1480
|
await ssh_client.disconnect()
|
|
1443
1481
|
|
|
1444
1482
|
# Print summary
|
|
1445
|
-
print(f"\n{'='*60}", file=sys.stderr)
|
|
1446
|
-
print(f"Remote conversion complete:", file=sys.stderr)
|
|
1447
|
-
print(f" Successful: {successful}", file=sys.stderr)
|
|
1448
|
-
|
|
1483
|
+
print(color.cyan(f"\n{'='*60}"), file=sys.stderr)
|
|
1484
|
+
print(color.cyan(f"Remote conversion complete:"), file=sys.stderr)
|
|
1485
|
+
print(color.green(f" Successful: {successful}"), file=sys.stderr)
|
|
1486
|
+
if failed > 0:
|
|
1487
|
+
print(color.yellow(f" Failed: {failed}"), file=sys.stderr)
|
|
1488
|
+
else:
|
|
1489
|
+
print(f" Failed: {failed}", file=sys.stderr)
|
|
1449
1490
|
print(f" Total: {len(files_to_convert)}", file=sys.stderr)
|
|
1450
|
-
print(f"{'='*60}", file=sys.stderr)
|
|
1491
|
+
print(color.cyan(f"{'='*60}"), file=sys.stderr)
|
|
1451
1492
|
|
|
1452
1493
|
return 0 if failed == 0 else 1
|
|
1453
1494
|
|
|
1454
1495
|
except SSHAuthError as e:
|
|
1455
|
-
print(f"Error: SSH authentication failed: {e}", file=sys.stderr)
|
|
1496
|
+
print(color.yellow(f"Error: SSH authentication failed: {e}"), file=sys.stderr)
|
|
1456
1497
|
print(" Check your SSH key, passphrase, or username", file=sys.stderr)
|
|
1457
1498
|
return 1
|
|
1458
1499
|
except SSHConnectionError as e:
|
|
1459
|
-
print(f"Error: SSH connection failed: {e}", file=sys.stderr)
|
|
1500
|
+
print(color.yellow(f"Error: SSH connection failed: {e}"), file=sys.stderr)
|
|
1460
1501
|
if hasattr(e, 'host') and hasattr(e, 'port'):
|
|
1461
1502
|
print(f" Host: {e.host}:{e.port}", file=sys.stderr)
|
|
1462
1503
|
return 1
|
|
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
|