mdify-cli 3.0.5__tar.gz → 3.0.7__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.7}/PKG-INFO +1 -1
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify/__init__.py +1 -1
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify/cli.py +59 -29
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify_cli.egg-info/PKG-INFO +1 -1
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/pyproject.toml +1 -1
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/LICENSE +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/README.md +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/assets/mdify.png +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify/__main__.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify/container.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify/docling_client.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify/formatting.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify/ssh/__init__.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify/ssh/client.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify/ssh/models.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify/ssh/remote_container.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify/ssh/transfer.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify_cli.egg-info/SOURCES.txt +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify_cli.egg-info/dependency_links.txt +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify_cli.egg-info/entry_points.txt +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify_cli.egg-info/requires.txt +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/mdify_cli.egg-info/top_level.txt +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/setup.cfg +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/tests/test_cli.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/tests/test_container.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/tests/test_docling_client.py +0 -0
- {mdify_cli-3.0.5 → mdify_cli-3.0.7}/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,16 +1319,43 @@ 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
|
+
conversion_output = None
|
|
1326
|
+
while conversion_attempt < 3 and not conversion_success:
|
|
1327
|
+
try:
|
|
1328
|
+
if conversion_attempt > 0 and not args.quiet:
|
|
1329
|
+
print(f" ↻ Conversion retry {conversion_attempt}...", file=sys.stderr)
|
|
1330
|
+
|
|
1331
|
+
conversion_output, _, conv_code = await ssh_client.run_command(convert_cmd, timeout=timeout)
|
|
1332
|
+
|
|
1333
|
+
if conv_code == 0:
|
|
1334
|
+
conversion_success = True
|
|
1335
|
+
break
|
|
1336
|
+
else:
|
|
1337
|
+
conversion_attempt += 1
|
|
1338
|
+
except Exception as conv_exc:
|
|
1339
|
+
if is_connection_error(conv_exc) and conversion_attempt < 2:
|
|
1340
|
+
conversion_attempt += 1
|
|
1341
|
+
if not args.quiet:
|
|
1342
|
+
print(f" ↻ Connection lost during conversion. Reconnecting (attempt {conversion_attempt})...", file=sys.stderr)
|
|
1343
|
+
try:
|
|
1344
|
+
await ssh_client.disconnect()
|
|
1345
|
+
except Exception:
|
|
1346
|
+
pass
|
|
1347
|
+
await ssh_client.connect()
|
|
1348
|
+
else:
|
|
1349
|
+
conversion_attempt += 1
|
|
1323
1350
|
|
|
1324
|
-
if
|
|
1325
|
-
print(f" ✗ Conversion failed
|
|
1351
|
+
if not conversion_success:
|
|
1352
|
+
print(f" ✗ Failed: Conversion failed after {conversion_attempt} attempt(s)", file=sys.stderr)
|
|
1326
1353
|
failed += 1
|
|
1327
1354
|
break
|
|
1328
1355
|
|
|
1329
1356
|
# Parse JSON response to extract markdown content
|
|
1330
1357
|
try:
|
|
1331
|
-
response_data = json.loads(
|
|
1358
|
+
response_data = json.loads(conversion_output)
|
|
1332
1359
|
|
|
1333
1360
|
# Extract content from response structure
|
|
1334
1361
|
# Actual format: {"document": {"md_content": "..."}, "status": "success"}
|
|
@@ -1357,7 +1384,7 @@ def main_async_remote(args) -> int:
|
|
|
1357
1384
|
markdown_content = str(result)
|
|
1358
1385
|
else:
|
|
1359
1386
|
# Ultimate fallback
|
|
1360
|
-
markdown_content =
|
|
1387
|
+
markdown_content = conversion_output
|
|
1361
1388
|
|
|
1362
1389
|
# Write markdown content to remote file
|
|
1363
1390
|
write_cmd = f"cat > {remote_output_path} << 'MDIFY_EOF'\n{markdown_content}\nMDIFY_EOF"
|
|
@@ -1368,10 +1395,10 @@ def main_async_remote(args) -> int:
|
|
|
1368
1395
|
failed += 1
|
|
1369
1396
|
break
|
|
1370
1397
|
|
|
1371
|
-
except (json.JSONDecodeError, KeyError, IndexError)
|
|
1372
|
-
print(f" ✗ Failed to parse conversion response
|
|
1398
|
+
except (json.JSONDecodeError, KeyError, IndexError):
|
|
1399
|
+
print(f" ✗ Failed to parse conversion response", file=sys.stderr)
|
|
1373
1400
|
if DEBUG:
|
|
1374
|
-
print(f" Response: {
|
|
1401
|
+
print(f" Response: {conversion_output[:500]}", file=sys.stderr)
|
|
1375
1402
|
failed += 1
|
|
1376
1403
|
break
|
|
1377
1404
|
|
|
@@ -1380,7 +1407,7 @@ def main_async_remote(args) -> int:
|
|
|
1380
1407
|
|
|
1381
1408
|
# Download result
|
|
1382
1409
|
if not args.quiet:
|
|
1383
|
-
print(f" Downloading result to {output_file}...", file=sys.stderr)
|
|
1410
|
+
print(color.cyan(f" Downloading result to {output_file}..."), file=sys.stderr)
|
|
1384
1411
|
|
|
1385
1412
|
await transfer_manager.download_file(
|
|
1386
1413
|
remote_path=remote_output_path,
|
|
@@ -1389,7 +1416,7 @@ def main_async_remote(args) -> int:
|
|
|
1389
1416
|
)
|
|
1390
1417
|
|
|
1391
1418
|
if not args.quiet:
|
|
1392
|
-
print(f" ✓ Download complete: {output_file}", file=sys.stderr)
|
|
1419
|
+
print(color.green(f" ✓ Download complete: {output_file}"), file=sys.stderr)
|
|
1393
1420
|
|
|
1394
1421
|
successful += 1
|
|
1395
1422
|
|
|
@@ -1401,7 +1428,7 @@ def main_async_remote(args) -> int:
|
|
|
1401
1428
|
if is_connection_error(e) and attempt == 0:
|
|
1402
1429
|
attempt += 1
|
|
1403
1430
|
if not args.quiet:
|
|
1404
|
-
print(" ↻ Connection lost. Reconnecting...", file=sys.stderr)
|
|
1431
|
+
print(color.yellow(" ↻ Connection lost. Reconnecting..."), file=sys.stderr)
|
|
1405
1432
|
try:
|
|
1406
1433
|
await ssh_client.disconnect()
|
|
1407
1434
|
except Exception:
|
|
@@ -1419,21 +1446,21 @@ def main_async_remote(args) -> int:
|
|
|
1419
1446
|
finally:
|
|
1420
1447
|
# Stop and remove container
|
|
1421
1448
|
if not args.quiet:
|
|
1422
|
-
print(f"\nStopping remote container...", file=sys.stderr)
|
|
1449
|
+
print(color.cyan(f"\nStopping remote container..."), file=sys.stderr)
|
|
1423
1450
|
|
|
1424
1451
|
try:
|
|
1425
1452
|
await remote_container.stop(force=False)
|
|
1426
1453
|
if not args.quiet:
|
|
1427
|
-
print(f"✓ Container stopped", file=sys.stderr)
|
|
1454
|
+
print(color.green(f"✓ Container stopped"), file=sys.stderr)
|
|
1428
1455
|
except Exception as e:
|
|
1429
1456
|
if not args.quiet:
|
|
1430
|
-
print(f"Warning: Failed to stop container: {e}", file=sys.stderr)
|
|
1457
|
+
print(color.yellow(f"Warning: Failed to stop container: {e}"), file=sys.stderr)
|
|
1431
1458
|
|
|
1432
1459
|
# Cleanup remote work directory
|
|
1433
1460
|
try:
|
|
1434
1461
|
await ssh_client.run_command(f"rm -rf {work_dir}")
|
|
1435
1462
|
if not args.quiet:
|
|
1436
|
-
print(f"✓ Cleaned up remote directory", file=sys.stderr)
|
|
1463
|
+
print(color.green(f"✓ Cleaned up remote directory"), file=sys.stderr)
|
|
1437
1464
|
except Exception as e:
|
|
1438
1465
|
if not args.quiet:
|
|
1439
1466
|
print(f"Warning: Failed to cleanup remote directory: {e}", file=sys.stderr)
|
|
@@ -1442,21 +1469,24 @@ def main_async_remote(args) -> int:
|
|
|
1442
1469
|
await ssh_client.disconnect()
|
|
1443
1470
|
|
|
1444
1471
|
# 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
|
-
|
|
1472
|
+
print(color.cyan(f"\n{'='*60}"), file=sys.stderr)
|
|
1473
|
+
print(color.cyan(f"Remote conversion complete:"), file=sys.stderr)
|
|
1474
|
+
print(color.green(f" Successful: {successful}"), file=sys.stderr)
|
|
1475
|
+
if failed > 0:
|
|
1476
|
+
print(color.yellow(f" Failed: {failed}"), file=sys.stderr)
|
|
1477
|
+
else:
|
|
1478
|
+
print(f" Failed: {failed}", file=sys.stderr)
|
|
1449
1479
|
print(f" Total: {len(files_to_convert)}", file=sys.stderr)
|
|
1450
|
-
print(f"{'='*60}", file=sys.stderr)
|
|
1480
|
+
print(color.cyan(f"{'='*60}"), file=sys.stderr)
|
|
1451
1481
|
|
|
1452
1482
|
return 0 if failed == 0 else 1
|
|
1453
1483
|
|
|
1454
1484
|
except SSHAuthError as e:
|
|
1455
|
-
print(f"Error: SSH authentication failed: {e}", file=sys.stderr)
|
|
1485
|
+
print(color.yellow(f"Error: SSH authentication failed: {e}"), file=sys.stderr)
|
|
1456
1486
|
print(" Check your SSH key, passphrase, or username", file=sys.stderr)
|
|
1457
1487
|
return 1
|
|
1458
1488
|
except SSHConnectionError as e:
|
|
1459
|
-
print(f"Error: SSH connection failed: {e}", file=sys.stderr)
|
|
1489
|
+
print(color.yellow(f"Error: SSH connection failed: {e}"), file=sys.stderr)
|
|
1460
1490
|
if hasattr(e, 'host') and hasattr(e, 'port'):
|
|
1461
1491
|
print(f" Host: {e.host}:{e.port}", file=sys.stderr)
|
|
1462
1492
|
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
|