diff --git a/organize.py b/organize.py index a194ba2..2d5f45d 100644 --- a/organize.py +++ b/organize.py @@ -571,17 +571,40 @@ def _write_logs(entries: list[dict[str, str]], with undo_path.open('w', encoding='utf-8') as f: f.write('@echo off\r\n') f.write('title Raskidator-3000 — Undo move\r\n') + f.write('setlocal enabledelayedexpansion\r\n') f.write('echo Restoring files...\r\n') f.write('echo.\r\n') + f.write('set FAILED=0\r\n') # Reverse: move destination → source for entry in reversed(entries): src = entry['source'] dst = entry['destination'] - f.write(f'move "{dst}" "{src}" >nul 2>&1\r\n') - if not f.write: # impossible but keep mypy happy - pass + # Normalise to backslashes for Windows + src = src.replace('/', '\\') + dst = dst.replace('/', '\\') + fname = dst.rsplit('\\', 1)[-1] if '\\' in dst else dst + + src_drive = src[:2] if len(src) >= 2 and src[1] == ':' else '' + dst_drive = dst[:2] if len(dst) >= 2 and dst[1] == ':' else '' + + if src_drive and dst_drive and src_drive.upper() != dst_drive.upper(): + # Cross-drive — robocopy /move + src_dir = src.rsplit('\\', 1)[0] if '\\' in src else src + dst_dir = dst.rsplit('\\', 1)[0] if '\\' in dst else dst + f.write(f'robocopy "{dst_dir}" "{src_dir}" "{fname}" /move /ndl /njh /njs /nfl >nul\r\n') + f.write(f'if errorlevel 8 echo FAILED (cross-drive: {src_drive} → {dst_drive})\r\n') + f.write(f'if errorlevel 8 set /a FAILED+=1\r\n') + else: + f.write(f'move "{dst}" "{src}"\r\n') + f.write(f'if errorlevel 1 echo FAILED: {fname}\r\n') + f.write(f'if errorlevel 1 set /a FAILED+=1\r\n') + f.write('echo.\r\n') + f.write(f'echo Restored {len(entries)} files. Failures: !FAILED!\r\n') + f.write('if !FAILED! gtr 0 (\r\n') + f.write(' echo.\r\n') + f.write(' echo Some files could not be restored.^ See above for details.\r\n') + f.write(')\r\n') f.write('echo.\r\n') - f.write(f'echo Restored {len(entries)} files.\r\n') f.write('pause\r\n')